@threadbase-sh/streamer 1.58.1 → 1.58.3

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
@@ -14996,8 +14996,8 @@ var init_regexes = __esm({
14996
14996
  _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
14997
14997
  ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
14998
14998
  ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
14999
- mac = (delimiter) => {
15000
- const escapedDelim = escapeRegex(delimiter ?? ":");
14999
+ mac = (delimiter2) => {
15000
+ const escapedDelim = escapeRegex(delimiter2 ?? ":");
15001
15001
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
15002
15002
  };
15003
15003
  cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -97168,6 +97168,25 @@ var init_devices_repository = __esm({
97168
97168
  }
97169
97169
  });
97170
97170
 
97171
+ // src/providers.ts
97172
+ function isProviderName(value) {
97173
+ return value === CLAUDE_CODE_PROVIDER || value === CODEX_CLI_PROVIDER;
97174
+ }
97175
+ function coerceProviderForRunner(value) {
97176
+ return isProviderName(value) ? value : CLAUDE_CODE_PROVIDER;
97177
+ }
97178
+ function isProviderResumable(_provider, availabilityResumable) {
97179
+ return availabilityResumable;
97180
+ }
97181
+ var CLAUDE_CODE_PROVIDER, CODEX_CLI_PROVIDER;
97182
+ var init_providers = __esm({
97183
+ "src/providers.ts"() {
97184
+ "use strict";
97185
+ CLAUDE_CODE_PROVIDER = "claude-code";
97186
+ CODEX_CLI_PROVIDER = "codex-cli";
97187
+ }
97188
+ });
97189
+
97171
97190
  // src/platform.ts
97172
97191
  function isWindowsExecutablePath(path2) {
97173
97192
  const dot = path2.lastIndexOf(".");
@@ -97294,6 +97313,39 @@ function resolveCodexExe() {
97294
97313
  _codexExe = "codex";
97295
97314
  return _codexExe;
97296
97315
  }
97316
+ function isExecutableFile(path2) {
97317
+ try {
97318
+ if (!(0, import_fs2.statSync)(path2).isFile()) return false;
97319
+ (0, import_fs2.accessSync)(path2, import_fs2.constants.X_OK);
97320
+ return true;
97321
+ } catch {
97322
+ return false;
97323
+ }
97324
+ }
97325
+ function locateExecutable(exe) {
97326
+ if (/[\\/]/.test(exe)) return isExecutableFile(exe) ? exe : null;
97327
+ const names = isWindows ? [
97328
+ ...isWindowsExecutablePath(exe) ? [exe] : [],
97329
+ ...[...WINDOWS_EXECUTABLE_EXTENSIONS].map((ext) => `${exe}${ext}`)
97330
+ ] : [exe];
97331
+ for (const dir of (process.env.PATH ?? "").split(import_path2.delimiter)) {
97332
+ if (!dir) continue;
97333
+ for (const name of names) {
97334
+ const candidate = (0, import_path2.join)(dir, name);
97335
+ if (isExecutableFile(candidate)) return candidate;
97336
+ }
97337
+ }
97338
+ return null;
97339
+ }
97340
+ function locateProviderExe(provider) {
97341
+ const isCodex = provider === CODEX_CLI_PROVIDER;
97342
+ const found = locateExecutable(isCodex ? resolveCodexExe() : resolveClaudeExe());
97343
+ if (found === null) {
97344
+ if (isCodex) clearCodexExeCache();
97345
+ else clearClaudeExeCache();
97346
+ }
97347
+ return found;
97348
+ }
97297
97349
  var import_child_process, import_fs2, import_os4, import_path2, isWindows, WINDOWS_EXECUTABLE_EXTENSIONS, _claudeExe, _codexExe;
97298
97350
  var init_platform = __esm({
97299
97351
  "src/platform.ts"() {
@@ -97302,30 +97354,12 @@ var init_platform = __esm({
97302
97354
  import_fs2 = require("fs");
97303
97355
  import_os4 = require("os");
97304
97356
  import_path2 = require("path");
97357
+ init_providers();
97305
97358
  isWindows = (0, import_os4.platform)() === "win32";
97306
97359
  WINDOWS_EXECUTABLE_EXTENSIONS = /* @__PURE__ */ new Set([".exe", ".cmd", ".bat"]);
97307
97360
  }
97308
97361
  });
97309
97362
 
97310
- // src/providers.ts
97311
- function isProviderName(value) {
97312
- return value === CLAUDE_CODE_PROVIDER || value === CODEX_CLI_PROVIDER;
97313
- }
97314
- function coerceProviderForRunner(value) {
97315
- return isProviderName(value) ? value : CLAUDE_CODE_PROVIDER;
97316
- }
97317
- function isProviderResumable(_provider, availabilityResumable) {
97318
- return availabilityResumable;
97319
- }
97320
- var CLAUDE_CODE_PROVIDER, CODEX_CLI_PROVIDER;
97321
- var init_providers = __esm({
97322
- "src/providers.ts"() {
97323
- "use strict";
97324
- CLAUDE_CODE_PROVIDER = "claude-code";
97325
- CODEX_CLI_PROVIDER = "codex-cli";
97326
- }
97327
- });
97328
-
97329
97363
  // node_modules/fast-glob/out/utils/array.js
97330
97364
  var require_array = __commonJS({
97331
97365
  "node_modules/fast-glob/out/utils/array.js"(exports2) {
@@ -99301,7 +99335,7 @@ var require_scan = __commonJS({
99301
99335
  var require_parse4 = __commonJS({
99302
99336
  "node_modules/picomatch/lib/parse.js"(exports2, module2) {
99303
99337
  "use strict";
99304
- var constants2 = require_constants5();
99338
+ var constants3 = require_constants5();
99305
99339
  var utils = require_utils2();
99306
99340
  var {
99307
99341
  MAX_LENGTH,
@@ -99309,7 +99343,7 @@ var require_parse4 = __commonJS({
99309
99343
  REGEX_NON_SPECIAL_CHARS,
99310
99344
  REGEX_SPECIAL_CHARS_BACKREF,
99311
99345
  REPLACEMENTS
99312
- } = constants2;
99346
+ } = constants3;
99313
99347
  var expandRange = (args, options) => {
99314
99348
  if (typeof options.expandRange === "function") {
99315
99349
  return options.expandRange(...args, options);
@@ -99515,7 +99549,7 @@ var require_parse4 = __commonJS({
99515
99549
  if (options.maxExtglobRecursion === false) {
99516
99550
  return { risky: false };
99517
99551
  }
99518
- const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants2.DEFAULT_MAX_EXTGLOB_RECURSION;
99552
+ const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants3.DEFAULT_MAX_EXTGLOB_RECURSION;
99519
99553
  const branches = splitTopLevel(body).map((branch) => branch.trim());
99520
99554
  if (branches.length > 1) {
99521
99555
  if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) {
@@ -99548,8 +99582,8 @@ var require_parse4 = __commonJS({
99548
99582
  const tokens = [bos];
99549
99583
  const capture = opts.capture ? "" : "?:";
99550
99584
  const win32 = utils.isWindows(options);
99551
- const PLATFORM_CHARS = constants2.globChars(win32);
99552
- const EXTGLOB_CHARS = constants2.extglobChars(PLATFORM_CHARS);
99585
+ const PLATFORM_CHARS = constants3.globChars(win32);
99586
+ const EXTGLOB_CHARS = constants3.extglobChars(PLATFORM_CHARS);
99553
99587
  const {
99554
99588
  DOT_LITERAL,
99555
99589
  PLUS_LITERAL,
@@ -100248,7 +100282,7 @@ var require_parse4 = __commonJS({
100248
100282
  NO_DOTS_SLASH,
100249
100283
  STAR,
100250
100284
  START_ANCHOR
100251
- } = constants2.globChars(win32);
100285
+ } = constants3.globChars(win32);
100252
100286
  const nodot = opts.dot ? NO_DOTS : NO_DOT;
100253
100287
  const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
100254
100288
  const capture = opts.capture ? "" : "?:";
@@ -100307,7 +100341,7 @@ var require_picomatch = __commonJS({
100307
100341
  var scan = require_scan();
100308
100342
  var parse3 = require_parse4();
100309
100343
  var utils = require_utils2();
100310
- var constants2 = require_constants5();
100344
+ var constants3 = require_constants5();
100311
100345
  var isObject2 = (val) => val && typeof val === "object" && !Array.isArray(val);
100312
100346
  var picomatch = (glob, options, returnState = false) => {
100313
100347
  if (Array.isArray(glob)) {
@@ -100435,7 +100469,7 @@ var require_picomatch = __commonJS({
100435
100469
  return /$^/;
100436
100470
  }
100437
100471
  };
100438
- picomatch.constants = constants2;
100472
+ picomatch.constants = constants3;
100439
100473
  module2.exports = picomatch;
100440
100474
  }
100441
100475
  });
@@ -101185,11 +101219,11 @@ var require_out = __commonJS({
101185
101219
  async.read(path2, getSettings(optionsOrSettingsOrCallback), callback);
101186
101220
  }
101187
101221
  exports2.stat = stat7;
101188
- function statSync17(path2, optionsOrSettings) {
101222
+ function statSync18(path2, optionsOrSettings) {
101189
101223
  const settings = getSettings(optionsOrSettings);
101190
101224
  return sync.read(path2, settings);
101191
101225
  }
101192
- exports2.statSync = statSync17;
101226
+ exports2.statSync = statSync18;
101193
101227
  function getSettings(settingsOrOptions = {}) {
101194
101228
  if (settingsOrOptions instanceof settings_1.default) {
101195
101229
  return settingsOrOptions;
@@ -113552,7 +113586,7 @@ var require_crc = __commonJS({
113552
113586
  var require_parser2 = __commonJS({
113553
113587
  "node_modules/pngjs/lib/parser.js"(exports2, module2) {
113554
113588
  "use strict";
113555
- var constants2 = require_constants7();
113589
+ var constants3 = require_constants7();
113556
113590
  var CrcCalculator = require_crc();
113557
113591
  var Parser = module2.exports = function(options, dependencies) {
113558
113592
  this._options = options;
@@ -113563,12 +113597,12 @@ var require_parser2 = __commonJS({
113563
113597
  this._palette = [];
113564
113598
  this._colorType = 0;
113565
113599
  this._chunks = {};
113566
- this._chunks[constants2.TYPE_IHDR] = this._handleIHDR.bind(this);
113567
- this._chunks[constants2.TYPE_IEND] = this._handleIEND.bind(this);
113568
- this._chunks[constants2.TYPE_IDAT] = this._handleIDAT.bind(this);
113569
- this._chunks[constants2.TYPE_PLTE] = this._handlePLTE.bind(this);
113570
- this._chunks[constants2.TYPE_tRNS] = this._handleTRNS.bind(this);
113571
- this._chunks[constants2.TYPE_gAMA] = this._handleGAMA.bind(this);
113600
+ this._chunks[constants3.TYPE_IHDR] = this._handleIHDR.bind(this);
113601
+ this._chunks[constants3.TYPE_IEND] = this._handleIEND.bind(this);
113602
+ this._chunks[constants3.TYPE_IDAT] = this._handleIDAT.bind(this);
113603
+ this._chunks[constants3.TYPE_PLTE] = this._handlePLTE.bind(this);
113604
+ this._chunks[constants3.TYPE_tRNS] = this._handleTRNS.bind(this);
113605
+ this._chunks[constants3.TYPE_gAMA] = this._handleGAMA.bind(this);
113572
113606
  this.read = dependencies.read;
113573
113607
  this.error = dependencies.error;
113574
113608
  this.metadata = dependencies.metadata;
@@ -113583,10 +113617,10 @@ var require_parser2 = __commonJS({
113583
113617
  };
113584
113618
  };
113585
113619
  Parser.prototype.start = function() {
113586
- this.read(constants2.PNG_SIGNATURE.length, this._parseSignature.bind(this));
113620
+ this.read(constants3.PNG_SIGNATURE.length, this._parseSignature.bind(this));
113587
113621
  };
113588
113622
  Parser.prototype._parseSignature = function(data) {
113589
- let signature = constants2.PNG_SIGNATURE;
113623
+ let signature = constants3.PNG_SIGNATURE;
113590
113624
  for (let i = 0; i < signature.length; i++) {
113591
113625
  if (data[i] !== signature[i]) {
113592
113626
  this.error(new Error("Invalid file signature"));
@@ -113603,7 +113637,7 @@ var require_parser2 = __commonJS({
113603
113637
  name += String.fromCharCode(data[i]);
113604
113638
  }
113605
113639
  let ancillary = Boolean(data[4] & 32);
113606
- if (!this._hasIHDR && type !== constants2.TYPE_IHDR) {
113640
+ if (!this._hasIHDR && type !== constants3.TYPE_IHDR) {
113607
113641
  this.error(new Error("Expected IHDR on beggining"));
113608
113642
  return;
113609
113643
  }
@@ -113651,7 +113685,7 @@ var require_parser2 = __commonJS({
113651
113685
  this.error(new Error("Unsupported bit depth " + depth));
113652
113686
  return;
113653
113687
  }
113654
- if (!(colorType in constants2.COLORTYPE_TO_BPP_MAP)) {
113688
+ if (!(colorType in constants3.COLORTYPE_TO_BPP_MAP)) {
113655
113689
  this.error(new Error("Unsupported color type"));
113656
113690
  return;
113657
113691
  }
@@ -113668,16 +113702,16 @@ var require_parser2 = __commonJS({
113668
113702
  return;
113669
113703
  }
113670
113704
  this._colorType = colorType;
113671
- let bpp = constants2.COLORTYPE_TO_BPP_MAP[this._colorType];
113705
+ let bpp = constants3.COLORTYPE_TO_BPP_MAP[this._colorType];
113672
113706
  this._hasIHDR = true;
113673
113707
  this.metadata({
113674
113708
  width,
113675
113709
  height,
113676
113710
  depth,
113677
113711
  interlace: Boolean(interlace),
113678
- palette: Boolean(colorType & constants2.COLORTYPE_PALETTE),
113679
- color: Boolean(colorType & constants2.COLORTYPE_COLOR),
113680
- alpha: Boolean(colorType & constants2.COLORTYPE_ALPHA),
113712
+ palette: Boolean(colorType & constants3.COLORTYPE_PALETTE),
113713
+ color: Boolean(colorType & constants3.COLORTYPE_COLOR),
113714
+ alpha: Boolean(colorType & constants3.COLORTYPE_ALPHA),
113681
113715
  bpp,
113682
113716
  colorType
113683
113717
  });
@@ -113701,7 +113735,7 @@ var require_parser2 = __commonJS({
113701
113735
  };
113702
113736
  Parser.prototype._parseTRNS = function(data) {
113703
113737
  this._crc.write(data);
113704
- if (this._colorType === constants2.COLORTYPE_PALETTE_COLOR) {
113738
+ if (this._colorType === constants3.COLORTYPE_PALETTE_COLOR) {
113705
113739
  if (this._palette.length === 0) {
113706
113740
  this.error(new Error("Transparency chunk must be after palette"));
113707
113741
  return;
@@ -113715,10 +113749,10 @@ var require_parser2 = __commonJS({
113715
113749
  }
113716
113750
  this.palette(this._palette);
113717
113751
  }
113718
- if (this._colorType === constants2.COLORTYPE_GRAYSCALE) {
113752
+ if (this._colorType === constants3.COLORTYPE_GRAYSCALE) {
113719
113753
  this.transColor([data.readUInt16BE(0)]);
113720
113754
  }
113721
- if (this._colorType === constants2.COLORTYPE_COLOR) {
113755
+ if (this._colorType === constants3.COLORTYPE_COLOR) {
113722
113756
  this.transColor([
113723
113757
  data.readUInt16BE(0),
113724
113758
  data.readUInt16BE(2),
@@ -113732,7 +113766,7 @@ var require_parser2 = __commonJS({
113732
113766
  };
113733
113767
  Parser.prototype._parseGAMA = function(data) {
113734
113768
  this._crc.write(data);
113735
- this.gamma(data.readUInt32BE(0) / constants2.GAMMA_DIVISION);
113769
+ this.gamma(data.readUInt32BE(0) / constants3.GAMMA_DIVISION);
113736
113770
  this._handleChunkEnd();
113737
113771
  };
113738
113772
  Parser.prototype._handleIDAT = function(length) {
@@ -113744,7 +113778,7 @@ var require_parser2 = __commonJS({
113744
113778
  };
113745
113779
  Parser.prototype._parseIDAT = function(length, data) {
113746
113780
  this._crc.write(data);
113747
- if (this._colorType === constants2.COLORTYPE_PALETTE_COLOR && this._palette.length === 0) {
113781
+ if (this._colorType === constants3.COLORTYPE_PALETTE_COLOR && this._palette.length === 0) {
113748
113782
  throw new Error("Expected palette not found");
113749
113783
  }
113750
113784
  this.inflateData(data);
@@ -114232,9 +114266,9 @@ var require_parser_async = __commonJS({
114232
114266
  var require_bitpacker = __commonJS({
114233
114267
  "node_modules/pngjs/lib/bitpacker.js"(exports2, module2) {
114234
114268
  "use strict";
114235
- var constants2 = require_constants7();
114269
+ var constants3 = require_constants7();
114236
114270
  module2.exports = function(dataIn, width, height, options) {
114237
- let outHasAlpha = [constants2.COLORTYPE_COLOR_ALPHA, constants2.COLORTYPE_ALPHA].indexOf(
114271
+ let outHasAlpha = [constants3.COLORTYPE_COLOR_ALPHA, constants3.COLORTYPE_ALPHA].indexOf(
114238
114272
  options.colorType
114239
114273
  ) !== -1;
114240
114274
  if (options.colorType === options.inputColorType) {
@@ -114254,11 +114288,11 @@ var require_bitpacker = __commonJS({
114254
114288
  }
114255
114289
  let data = options.bitDepth !== 16 ? dataIn : new Uint16Array(dataIn.buffer);
114256
114290
  let maxValue = 255;
114257
- let inBpp = constants2.COLORTYPE_TO_BPP_MAP[options.inputColorType];
114291
+ let inBpp = constants3.COLORTYPE_TO_BPP_MAP[options.inputColorType];
114258
114292
  if (inBpp === 4 && !options.inputHasAlpha) {
114259
114293
  inBpp = 3;
114260
114294
  }
114261
- let outBpp = constants2.COLORTYPE_TO_BPP_MAP[options.colorType];
114295
+ let outBpp = constants3.COLORTYPE_TO_BPP_MAP[options.colorType];
114262
114296
  if (options.bitDepth === 16) {
114263
114297
  maxValue = 65535;
114264
114298
  outBpp *= 2;
@@ -114282,24 +114316,24 @@ var require_bitpacker = __commonJS({
114282
114316
  let blue;
114283
114317
  let alpha = maxValue;
114284
114318
  switch (options.inputColorType) {
114285
- case constants2.COLORTYPE_COLOR_ALPHA:
114319
+ case constants3.COLORTYPE_COLOR_ALPHA:
114286
114320
  alpha = data[inIndex + 3];
114287
114321
  red = data[inIndex];
114288
114322
  green = data[inIndex + 1];
114289
114323
  blue = data[inIndex + 2];
114290
114324
  break;
114291
- case constants2.COLORTYPE_COLOR:
114325
+ case constants3.COLORTYPE_COLOR:
114292
114326
  red = data[inIndex];
114293
114327
  green = data[inIndex + 1];
114294
114328
  blue = data[inIndex + 2];
114295
114329
  break;
114296
- case constants2.COLORTYPE_ALPHA:
114330
+ case constants3.COLORTYPE_ALPHA:
114297
114331
  alpha = data[inIndex + 1];
114298
114332
  red = data[inIndex];
114299
114333
  green = red;
114300
114334
  blue = red;
114301
114335
  break;
114302
- case constants2.COLORTYPE_GRAYSCALE:
114336
+ case constants3.COLORTYPE_GRAYSCALE:
114303
114337
  red = data[inIndex];
114304
114338
  green = red;
114305
114339
  blue = red;
@@ -114332,8 +114366,8 @@ var require_bitpacker = __commonJS({
114332
114366
  for (let x = 0; x < width; x++) {
114333
114367
  let rgba = getRGBA(data, inIndex);
114334
114368
  switch (options.colorType) {
114335
- case constants2.COLORTYPE_COLOR_ALPHA:
114336
- case constants2.COLORTYPE_COLOR:
114369
+ case constants3.COLORTYPE_COLOR_ALPHA:
114370
+ case constants3.COLORTYPE_COLOR:
114337
114371
  if (options.bitDepth === 8) {
114338
114372
  outData[outIndex] = rgba.red;
114339
114373
  outData[outIndex + 1] = rgba.green;
@@ -114350,8 +114384,8 @@ var require_bitpacker = __commonJS({
114350
114384
  }
114351
114385
  }
114352
114386
  break;
114353
- case constants2.COLORTYPE_ALPHA:
114354
- case constants2.COLORTYPE_GRAYSCALE: {
114387
+ case constants3.COLORTYPE_ALPHA:
114388
+ case constants3.COLORTYPE_GRAYSCALE: {
114355
114389
  let grayscale = (rgba.red + rgba.green + rgba.blue) / 3;
114356
114390
  if (options.bitDepth === 8) {
114357
114391
  outData[outIndex] = grayscale;
@@ -114524,7 +114558,7 @@ var require_filter_pack = __commonJS({
114524
114558
  var require_packer = __commonJS({
114525
114559
  "node_modules/pngjs/lib/packer.js"(exports2, module2) {
114526
114560
  "use strict";
114527
- var constants2 = require_constants7();
114561
+ var constants3 = require_constants7();
114528
114562
  var CrcStream = require_crc();
114529
114563
  var bitPacker = require_bitpacker();
114530
114564
  var filter = require_filter_pack();
@@ -114537,23 +114571,23 @@ var require_packer = __commonJS({
114537
114571
  options.inputHasAlpha = options.inputHasAlpha != null ? options.inputHasAlpha : true;
114538
114572
  options.deflateFactory = options.deflateFactory || zlib.createDeflate;
114539
114573
  options.bitDepth = options.bitDepth || 8;
114540
- options.colorType = typeof options.colorType === "number" ? options.colorType : constants2.COLORTYPE_COLOR_ALPHA;
114541
- options.inputColorType = typeof options.inputColorType === "number" ? options.inputColorType : constants2.COLORTYPE_COLOR_ALPHA;
114574
+ options.colorType = typeof options.colorType === "number" ? options.colorType : constants3.COLORTYPE_COLOR_ALPHA;
114575
+ options.inputColorType = typeof options.inputColorType === "number" ? options.inputColorType : constants3.COLORTYPE_COLOR_ALPHA;
114542
114576
  if ([
114543
- constants2.COLORTYPE_GRAYSCALE,
114544
- constants2.COLORTYPE_COLOR,
114545
- constants2.COLORTYPE_COLOR_ALPHA,
114546
- constants2.COLORTYPE_ALPHA
114577
+ constants3.COLORTYPE_GRAYSCALE,
114578
+ constants3.COLORTYPE_COLOR,
114579
+ constants3.COLORTYPE_COLOR_ALPHA,
114580
+ constants3.COLORTYPE_ALPHA
114547
114581
  ].indexOf(options.colorType) === -1) {
114548
114582
  throw new Error(
114549
114583
  "option color type:" + options.colorType + " is not supported at present"
114550
114584
  );
114551
114585
  }
114552
114586
  if ([
114553
- constants2.COLORTYPE_GRAYSCALE,
114554
- constants2.COLORTYPE_COLOR,
114555
- constants2.COLORTYPE_COLOR_ALPHA,
114556
- constants2.COLORTYPE_ALPHA
114587
+ constants3.COLORTYPE_GRAYSCALE,
114588
+ constants3.COLORTYPE_COLOR,
114589
+ constants3.COLORTYPE_COLOR_ALPHA,
114590
+ constants3.COLORTYPE_ALPHA
114557
114591
  ].indexOf(options.inputColorType) === -1) {
114558
114592
  throw new Error(
114559
114593
  "option input color type:" + options.inputColorType + " is not supported at present"
@@ -114577,7 +114611,7 @@ var require_packer = __commonJS({
114577
114611
  };
114578
114612
  Packer.prototype.filterData = function(data, width, height) {
114579
114613
  let packedData = bitPacker(data, width, height, this._options);
114580
- let bpp = constants2.COLORTYPE_TO_BPP_MAP[this._options.colorType];
114614
+ let bpp = constants3.COLORTYPE_TO_BPP_MAP[this._options.colorType];
114581
114615
  let filteredData = filter(packedData, width, height, this._options, bpp);
114582
114616
  return filteredData;
114583
114617
  };
@@ -114597,8 +114631,8 @@ var require_packer = __commonJS({
114597
114631
  };
114598
114632
  Packer.prototype.packGAMA = function(gamma) {
114599
114633
  let buf = Buffer.alloc(4);
114600
- buf.writeUInt32BE(Math.floor(gamma * constants2.GAMMA_DIVISION), 0);
114601
- return this._packChunk(constants2.TYPE_gAMA, buf);
114634
+ buf.writeUInt32BE(Math.floor(gamma * constants3.GAMMA_DIVISION), 0);
114635
+ return this._packChunk(constants3.TYPE_gAMA, buf);
114602
114636
  };
114603
114637
  Packer.prototype.packIHDR = function(width, height) {
114604
114638
  let buf = Buffer.alloc(13);
@@ -114609,13 +114643,13 @@ var require_packer = __commonJS({
114609
114643
  buf[10] = 0;
114610
114644
  buf[11] = 0;
114611
114645
  buf[12] = 0;
114612
- return this._packChunk(constants2.TYPE_IHDR, buf);
114646
+ return this._packChunk(constants3.TYPE_IHDR, buf);
114613
114647
  };
114614
114648
  Packer.prototype.packIDAT = function(data) {
114615
- return this._packChunk(constants2.TYPE_IDAT, data);
114649
+ return this._packChunk(constants3.TYPE_IDAT, data);
114616
114650
  };
114617
114651
  Packer.prototype.packIEND = function() {
114618
- return this._packChunk(constants2.TYPE_IEND, null);
114652
+ return this._packChunk(constants3.TYPE_IEND, null);
114619
114653
  };
114620
114654
  }
114621
114655
  });
@@ -114626,7 +114660,7 @@ var require_packer_async = __commonJS({
114626
114660
  "use strict";
114627
114661
  var util = require("util");
114628
114662
  var Stream = require("stream");
114629
- var constants2 = require_constants7();
114663
+ var constants3 = require_constants7();
114630
114664
  var Packer = require_packer();
114631
114665
  var PackerAsync = module2.exports = function(opt) {
114632
114666
  Stream.call(this);
@@ -114637,7 +114671,7 @@ var require_packer_async = __commonJS({
114637
114671
  };
114638
114672
  util.inherits(PackerAsync, Stream);
114639
114673
  PackerAsync.prototype.pack = function(data, width, height, gamma) {
114640
- this.emit("data", Buffer.from(constants2.PNG_SIGNATURE));
114674
+ this.emit("data", Buffer.from(constants3.PNG_SIGNATURE));
114641
114675
  this.emit("data", this._packer.packIHDR(width, height));
114642
114676
  if (gamma) {
114643
114677
  this.emit("data", this._packer.packGAMA(gamma));
@@ -114965,7 +114999,7 @@ var require_packer_sync = __commonJS({
114965
114999
  if (!zlib.deflateSync) {
114966
115000
  hasSyncZlib = false;
114967
115001
  }
114968
- var constants2 = require_constants7();
115002
+ var constants3 = require_constants7();
114969
115003
  var Packer = require_packer();
114970
115004
  module2.exports = function(metaData, opt) {
114971
115005
  if (!hasSyncZlib) {
@@ -114976,7 +115010,7 @@ var require_packer_sync = __commonJS({
114976
115010
  let options = opt || {};
114977
115011
  let packer = new Packer(options);
114978
115012
  let chunks = [];
114979
- chunks.push(Buffer.from(constants2.PNG_SIGNATURE));
115013
+ chunks.push(Buffer.from(constants3.PNG_SIGNATURE));
114980
115014
  chunks.push(packer.packIHDR(metaData.width, metaData.height));
114981
115015
  if (metaData.gamma) {
114982
115016
  chunks.push(packer.packGAMA(metaData.gamma));
@@ -122894,6 +122928,7 @@ var init_live_session_manager = __esm({
122894
122928
  "use strict";
122895
122929
  import_path28 = require("path");
122896
122930
  init_codex_pty_runner();
122931
+ init_platform();
122897
122932
  init_providers();
122898
122933
  init_remote_session_runner();
122899
122934
  init_pty_manager();
@@ -122926,11 +122961,13 @@ var init_live_session_manager = __esm({
122926
122961
  async start(sessionId, options) {
122927
122962
  const provider = options.provider ?? CLAUDE_CODE_PROVIDER;
122928
122963
  const runner = this.assertSupportedProvider(provider, options.projectPath);
122964
+ this.assertProviderInstalled(provider);
122929
122965
  return runner.start(sessionId, options);
122930
122966
  }
122931
122967
  async startFresh(options) {
122932
122968
  const provider = options.provider ?? CLAUDE_CODE_PROVIDER;
122933
122969
  const runner = this.assertSupportedProvider(provider, options.projectPath);
122970
+ this.assertProviderInstalled(provider);
122934
122971
  return runner.startFresh(options);
122935
122972
  }
122936
122973
  /**
@@ -122949,6 +122986,7 @@ var init_live_session_manager = __esm({
122949
122986
  err.statusCode = 501;
122950
122987
  throw err;
122951
122988
  }
122989
+ this.assertProviderInstalled(provider);
122952
122990
  return runner.startFork(options);
122953
122991
  }
122954
122992
  sendInput(sessionId, input) {
@@ -123030,6 +123068,30 @@ var init_live_session_manager = __esm({
123030
123068
  }
123031
123069
  throw new Error(`Session not found: ${sessionId}`);
123032
123070
  }
123071
+ /**
123072
+ * Refuse before spawning when the provider's CLI is not on this machine.
123073
+ *
123074
+ * Without this the spawn "succeeds": on POSIX execvp fails inside the forked
123075
+ * child, so a session appears, exits ~12ms later with code 1 and no output,
123076
+ * and the caller is told only that it "exited before becoming ready" — or,
123077
+ * on the Claude resume path, is told nothing at all, since that path answers
123078
+ * 200 before the process has had a chance to die. Every start route funnels
123079
+ * through here, so one check covers start, resume, adopt and fork.
123080
+ *
123081
+ * 503, not 500: the request was well-formed and the fault is this machine's
123082
+ * environment. `code` is what mobile branches on (it reads `errBody.code`),
123083
+ * and `PROVIDER_NOT_INSTALLED` is a remediation string it already knows.
123084
+ */
123085
+ assertProviderInstalled(provider) {
123086
+ if (locateProviderExe(provider) !== null) return;
123087
+ const command = provider === CODEX_CLI_PROVIDER ? "codex" : "claude";
123088
+ const err = new Error(
123089
+ `The ${command} command was not found on this server. Install the ${provider} CLI, or make sure it is on the PATH the streamer runs with.`
123090
+ );
123091
+ err.statusCode = 503;
123092
+ err.code = "PROVIDER_NOT_INSTALLED";
123093
+ throw err;
123094
+ }
123033
123095
  assertSupportedProvider(provider, projectPath) {
123034
123096
  if (this.remoteRunner) return this.remoteRunner;
123035
123097
  const runner = this.runners.get(provider);
@@ -126363,10 +126425,10 @@ var require_truncate = __commonJS({
126363
126425
  "node_modules/semver/functions/truncate.js"(exports2, module2) {
126364
126426
  "use strict";
126365
126427
  var parse3 = require_parse5();
126366
- var constants2 = require_constants8();
126428
+ var constants3 = require_constants8();
126367
126429
  var SemVer = require_semver();
126368
126430
  var truncate = (version2, truncation, options) => {
126369
- if (!constants2.RELEASE_TYPES.includes(truncation)) {
126431
+ if (!constants3.RELEASE_TYPES.includes(truncation)) {
126370
126432
  return null;
126371
126433
  }
126372
126434
  const clonedVersion = cloneInputVersion(version2, options);
@@ -127415,7 +127477,7 @@ var require_semver2 = __commonJS({
127415
127477
  "node_modules/semver/index.js"(exports2, module2) {
127416
127478
  "use strict";
127417
127479
  var internalRe = require_re();
127418
- var constants2 = require_constants8();
127480
+ var constants3 = require_constants8();
127419
127481
  var SemVer = require_semver();
127420
127482
  var identifiers = require_identifiers();
127421
127483
  var parse3 = require_parse5();
@@ -127499,8 +127561,8 @@ var require_semver2 = __commonJS({
127499
127561
  re: internalRe.re,
127500
127562
  src: internalRe.src,
127501
127563
  tokens: internalRe.t,
127502
- SEMVER_SPEC_VERSION: constants2.SEMVER_SPEC_VERSION,
127503
- RELEASE_TYPES: constants2.RELEASE_TYPES,
127564
+ SEMVER_SPEC_VERSION: constants3.SEMVER_SPEC_VERSION,
127565
+ RELEASE_TYPES: constants3.RELEASE_TYPES,
127504
127566
  compareIdentifiers: identifiers.compareIdentifiers,
127505
127567
  rcompareIdentifiers: identifiers.rcompareIdentifiers
127506
127568
  };
@@ -134499,7 +134561,9 @@ var corsMiddleware = (configValue) => {
134499
134561
  // src/api/middleware/error.middleware.ts
134500
134562
  var errorMiddleware = (err, c) => {
134501
134563
  const message = err instanceof Error ? err.message : "Internal server error";
134502
- return c.json({ error: message }, 500);
134564
+ const { statusCode, code } = err;
134565
+ const status = typeof statusCode === "number" && statusCode >= 400 && statusCode <= 599 ? statusCode : 500;
134566
+ return c.json(typeof code === "string" ? { error: message, code } : { error: message }, status);
134503
134567
  };
134504
134568
 
134505
134569
  // src/api/routes/backup.routes.ts
@@ -134924,6 +134988,7 @@ var createDeviceRoutes = (deps) => {
134924
134988
  // src/api/routes/diagnostics.routes.ts
134925
134989
  var import_fs3 = require("fs");
134926
134990
  init_platform();
134991
+ init_providers();
134927
134992
 
134928
134993
  // src/services/diagnostics/diagnostics.ts
134929
134994
  var DIAGNOSTICS_CONTRACT_VERSION = 1;
@@ -135045,24 +135110,26 @@ function computeBootToken() {
135045
135110
  }
135046
135111
 
135047
135112
  // src/api/routes/diagnostics.routes.ts
135048
- function providerCheck(name, resolve4) {
135113
+ function providerCheck(name) {
135049
135114
  try {
135050
- const exe = resolve4();
135051
- return {
135052
- id: `provider:${name}`,
135053
- status: "ok",
135054
- summary: `${name} CLI is installed.`,
135055
- remediation: "NONE",
135056
- detail: { location: redactPath(exe) }
135057
- };
135115
+ const exe = locateProviderExe(name);
135116
+ if (exe !== null) {
135117
+ return {
135118
+ id: `provider:${name}`,
135119
+ status: "ok",
135120
+ summary: `${name} CLI is installed.`,
135121
+ remediation: "NONE",
135122
+ detail: { location: redactPath(exe) }
135123
+ };
135124
+ }
135058
135125
  } catch {
135059
- return {
135060
- id: `provider:${name}`,
135061
- status: "failed",
135062
- summary: `${name} CLI could not be located. Sessions for this provider cannot start.`,
135063
- remediation: "PROVIDER_NOT_INSTALLED"
135064
- };
135065
135126
  }
135127
+ return {
135128
+ id: `provider:${name}`,
135129
+ status: "failed",
135130
+ summary: `${name} CLI could not be located. Sessions for this provider cannot start.`,
135131
+ remediation: "PROVIDER_NOT_INSTALLED"
135132
+ };
135066
135133
  }
135067
135134
  var createDiagnosticsRoutes = (deps) => {
135068
135135
  const app = new Hono2();
@@ -135075,8 +135142,8 @@ var createDiagnosticsRoutes = (deps) => {
135075
135142
  remediation: "NONE",
135076
135143
  detail: { version: getVersion(), uptimeSeconds: Math.floor(process.uptime()) }
135077
135144
  });
135078
- checks.push(providerCheck("claude-code", resolveClaudeExe));
135079
- checks.push(providerCheck("codex-cli", resolveCodexExe));
135145
+ checks.push(providerCheck(CLAUDE_CODE_PROVIDER));
135146
+ checks.push(providerCheck(CODEX_CLI_PROVIDER));
135080
135147
  const cacheAlert = deps.cacheMonitor()?.healthzField();
135081
135148
  checks.push(
135082
135149
  cacheAlert ? {
@@ -136193,7 +136260,6 @@ var createProjectRoutes = (deps) => {
136193
136260
  };
136194
136261
 
136195
136262
  // src/api/routes/providers.routes.ts
136196
- init_platform();
136197
136263
  init_providers();
136198
136264
 
136199
136265
  // src/services/providers/providerHealth.ts
@@ -136238,7 +136304,10 @@ function parseVersionOutput(output) {
136238
136304
  const match2 = output.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
136239
136305
  return match2 ? match2[0] : null;
136240
136306
  }
136307
+ var versionByExe = /* @__PURE__ */ new Map();
136241
136308
  function runVersion(exe) {
136309
+ const cached4 = versionByExe.get(exe);
136310
+ if (cached4 !== void 0) return Promise.resolve(cached4);
136242
136311
  const viaShell = isWindows && /\.(?:cmd|bat)$/i.test(exe);
136243
136312
  const file2 = viaShell ? `"${exe}"` : exe;
136244
136313
  return new Promise((resolve4) => {
@@ -136248,7 +136317,9 @@ function runVersion(exe) {
136248
136317
  { timeout: VERSION_TIMEOUT_MS, shell: viaShell, windowsHide: true },
136249
136318
  (err, stdout2, stderr) => {
136250
136319
  if (err && !stdout2 && !stderr) return resolve4(null);
136251
- resolve4(parseVersionOutput(`${stdout2}${stderr}`));
136320
+ const version2 = parseVersionOutput(`${stdout2}${stderr}`);
136321
+ if (version2 !== null) versionByExe.set(exe, version2);
136322
+ resolve4(version2);
136252
136323
  }
136253
136324
  );
136254
136325
  });
@@ -136292,13 +136363,16 @@ function compareSemver(a, b2) {
136292
136363
  if (pb2.pre === null) return -1;
136293
136364
  return pa.pre < pb2.pre ? -1 : 1;
136294
136365
  }
136295
- async function providerHealth(name, resolveExe, detect = runVersion) {
136366
+ async function providerHealth(name, locateExe = () => locateProviderExe(name), detect = runVersion) {
136296
136367
  const verifiedAgainst = VERIFIED_AGAINST[name];
136297
136368
  const capabilities = capabilitiesFor(name);
136298
- let exe;
136369
+ let exe = null;
136299
136370
  try {
136300
- exe = resolveExe();
136371
+ exe = locateExe();
136301
136372
  } catch {
136373
+ exe = null;
136374
+ }
136375
+ if (exe === null) {
136302
136376
  return {
136303
136377
  name,
136304
136378
  available: false,
@@ -136335,8 +136409,8 @@ var createProviderRoutes = () => {
136335
136409
  const app = new Hono2();
136336
136410
  app.get("/", async (c) => {
136337
136411
  const providers = await Promise.all([
136338
- providerHealth(CLAUDE_CODE_PROVIDER, resolveClaudeExe),
136339
- providerHealth(CODEX_CLI_PROVIDER, resolveCodexExe)
136412
+ providerHealth(CLAUDE_CODE_PROVIDER),
136413
+ providerHealth(CODEX_CLI_PROVIDER)
136340
136414
  ]);
136341
136415
  return c.json({ providers });
136342
136416
  });
@@ -148307,7 +148381,10 @@ var SessionHandlers = class {
148307
148381
  });
148308
148382
  this.sessionStore.addManaged(session);
148309
148383
  this.registryBoot.recordSessionSpawn(session);
148310
- const { outcome } = await this.deps.waitForStartupOutcome(session.id, START_READY_TIMEOUT_MS);
148384
+ const { outcome, session: settled } = await this.deps.waitForStartupOutcome(
148385
+ session.id,
148386
+ START_READY_TIMEOUT_MS
148387
+ );
148311
148388
  const current = this.sessionStore.get(session.id, this.deps.ptyAttachedIds());
148312
148389
  if (outcome === "ready" && current) {
148313
148390
  json2(res, 200, { session: current });
@@ -148315,7 +148392,7 @@ var SessionHandlers = class {
148315
148392
  json2(res, 502, {
148316
148393
  id: session.id,
148317
148394
  status: "idle",
148318
- error: current.failureReason ?? "Session exited before becoming ready"
148395
+ error: settled?.failureReason ?? "Session exited before becoming ready"
148319
148396
  });
148320
148397
  } else {
148321
148398
  json2(res, 202, { id: session.id, status: "pending" });
@@ -148329,11 +148406,16 @@ var SessionHandlers = class {
148329
148406
  } catch (err) {
148330
148407
  const message = err instanceof Error ? err.message : "Failed to start session";
148331
148408
  const statusCode = typeof err.statusCode === "number" ? err.statusCode : 500;
148409
+ const code = err.code;
148332
148410
  this.log.error(`[start] failed to start session: ${message}`, {
148333
148411
  event: "session.start_failed",
148334
148412
  error: message
148335
148413
  });
148336
- json2(res, statusCode, { error: message });
148414
+ json2(
148415
+ res,
148416
+ statusCode,
148417
+ typeof code === "string" ? { error: message, code } : { error: message }
148418
+ );
148337
148419
  }
148338
148420
  }
148339
148421
  async handleSetSessionName(sessionId, req, res) {
@@ -149030,7 +149112,7 @@ var PairTokenStore = class {
149030
149112
  };
149031
149113
  }
149032
149114
  /**
149033
- * Whether `consume` would succeed right now, WITHOUT spending the token.
149115
+ * What `consume` would answer right now, WITHOUT spending the token.
149034
149116
  *
149035
149117
  * Exists so a caller can reject a bad token before doing any work, and still
149036
149118
  * spend the token only once the work has succeeded. A pair token is
@@ -149039,10 +149121,14 @@ var PairTokenStore = class {
149039
149121
  * indistinguishable from an attacker replaying a photographed code, which is
149040
149122
  * the one signal `design.md` §2.6 designates as replay detection.
149041
149123
  *
149042
- * Advisory, not a reservation: it takes no lock and holds nothing. The
149043
- * authoritative answer is still `consume`'s.
149124
+ * **Named for its relationship to `consume`, deliberately.** It reserves
149125
+ * nothing and takes no lock, so two callers can both be told `{ ok: true }`
149126
+ * for the same token. A name like `verify` would read as a gate that had
149127
+ * decided something, and inviting a caller to act on this alone is precisely
149128
+ * the misuse the ordering it enables exists to prevent. A reader who sees
149129
+ * `wouldConsume` asks where the `consume` is, which is the right question.
149044
149130
  */
149045
- verify(token) {
149131
+ wouldConsume(token) {
149046
149132
  const result = this.check(token);
149047
149133
  return result.ok ? { ok: true } : result;
149048
149134
  }
@@ -149088,6 +149174,7 @@ var PairTokenStore = class {
149088
149174
  };
149089
149175
 
149090
149176
  // src/server.ts
149177
+ init_platform();
149091
149178
  init_providers();
149092
149179
  init_remote_session_runner();
149093
149180
 
@@ -150150,7 +150237,15 @@ function createLiveSessionOptions(deps) {
150150
150237
  // grace-timer/idle-reaper hold (statusSource "shutdown") apart from a
150151
150238
  // genuine process exit ("process-exit"), and reports both as
150152
150239
  // `lifecycle: "completed"`. See managedToResponse in session-store.ts.
150153
- ...session.statusSource != null && { statusSource: session.statusSource }
150240
+ ...session.statusSource != null && { statusSource: session.statusSource },
150241
+ // Why a session died, not just that it did. Without this the store's
150242
+ // copy has no failureReason, so managedToResponse falls through to
150243
+ // `lifecycle: "completed"` (see session-store.ts) and a session that
150244
+ // never started — missing CLI, missing project dir — is reported to
150245
+ // every client as one that finished normally. Guarded like its
150246
+ // neighbours: a later transition must not blank a recorded failure.
150247
+ ...session.failureReason != null && { failureReason: session.failureReason },
150248
+ ...session.failureCode != null && { failureCode: session.failureCode }
150154
150249
  });
150155
150250
  deps.managedSessionsRepo()?.recordStatus(
150156
150251
  session.id,
@@ -153649,6 +153744,41 @@ var StreamerServer = class {
153649
153744
  json2(res, 503, body);
153650
153745
  return true;
153651
153746
  }
153747
+ /**
153748
+ * Say which provider CLIs this machine can actually launch.
153749
+ *
153750
+ * The operator cannot discover this case unaided: under launchd/Task
153751
+ * Scheduler the service inherits a stripped PATH, so a CLI that works
153752
+ * perfectly in their terminal is invisible to the service, and every session
153753
+ * start dies milliseconds in. `/api/diagnostics` answers it too, but only for
153754
+ * someone who already suspects it.
153755
+ *
153756
+ * Availability only, never a version — `--version` costs a process spawn per
153757
+ * provider (85ms for claude here) and belongs on the first request that wants
153758
+ * it, not on boot.
153759
+ *
153760
+ * Called AFTER the port is bound, which is not cosmetic. This is the first
153761
+ * caller of the exe resolvers in the process, so the memo is cold by
153762
+ * definition and each provider pays one synchronous `which` / `where.exe`
153763
+ * (platform.ts) with a 3s timeout. On POSIX that is 3ms found, 7ms missing.
153764
+ * Windows is the risk — `where.exe` is slower, `execFileSync` blocks the
153765
+ * event loop, and Task Scheduler's stripped PATH is exactly where a miss
153766
+ * pays the full timeout — so the worst case is ~6s of two blocking lookups.
153767
+ * After `listen()` that delays the first requests on a box that cannot start
153768
+ * a session anyway; before it, it would have delayed binding the port.
153769
+ */
153770
+ logProviderAvailability() {
153771
+ for (const provider of [CLAUDE_CODE_PROVIDER, CODEX_CLI_PROVIDER]) {
153772
+ if (locateProviderExe(provider)) {
153773
+ this.log.info(`Provider ${provider}: found`, { event: "config.provider", provider });
153774
+ } else {
153775
+ this.log.warn(`Provider ${provider}: not found on PATH \u2014 sessions cannot start`, {
153776
+ event: "config.provider_missing",
153777
+ provider
153778
+ });
153779
+ }
153780
+ }
153781
+ }
153652
153782
  async listen(port, opts) {
153653
153783
  if (this.featureFlags.ptyHost) {
153654
153784
  try {
@@ -153709,6 +153839,7 @@ var StreamerServer = class {
153709
153839
  event: "server.listening",
153710
153840
  ...this.host !== void 0 && { host: this.host }
153711
153841
  });
153842
+ this.logProviderAvailability();
153712
153843
  try {
153713
153844
  this.runtimeStore = RuntimeStore.open(this.runtimeDbPath);
153714
153845
  this.managedSessionsRepo = new ManagedSessionsRepository(this.runtimeStore.getDatabase());
@@ -154085,8 +154216,14 @@ var StreamerServer = class {
154085
154216
  json2(res, 400, { error: "Missing token or clientPublicKey" });
154086
154217
  return;
154087
154218
  }
154088
- const precheck = this.pairTokens.verify(token);
154219
+ const precheck = this.pairTokens.wouldConsume(token);
154089
154220
  if (!precheck.ok) {
154221
+ if (precheck.reason === "used") {
154222
+ this.log.warn(
154223
+ "[pair] a pair token was replayed. If you did not just pair a device, check the paired-devices list and revoke anything you do not recognise.",
154224
+ { event: "pair.token_replayed", ip }
154225
+ );
154226
+ }
154090
154227
  json2(res, 401, { error: `Pair token ${precheck.reason}` });
154091
154228
  return;
154092
154229
  }