@threadbase-sh/streamer 1.58.0 → 1.58.2
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 +296 -129
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +215 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +257 -91
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 = (
|
|
15000
|
-
const escapedDelim = escapeRegex(
|
|
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
|
|
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
|
-
} =
|
|
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 :
|
|
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 =
|
|
99552
|
-
const EXTGLOB_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
|
-
} =
|
|
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
|
|
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 =
|
|
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
|
|
101222
|
+
function statSync18(path2, optionsOrSettings) {
|
|
101189
101223
|
const settings = getSettings(optionsOrSettings);
|
|
101190
101224
|
return sync.read(path2, settings);
|
|
101191
101225
|
}
|
|
101192
|
-
exports2.statSync =
|
|
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
|
|
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[
|
|
113567
|
-
this._chunks[
|
|
113568
|
-
this._chunks[
|
|
113569
|
-
this._chunks[
|
|
113570
|
-
this._chunks[
|
|
113571
|
-
this._chunks[
|
|
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(
|
|
113620
|
+
this.read(constants3.PNG_SIGNATURE.length, this._parseSignature.bind(this));
|
|
113587
113621
|
};
|
|
113588
113622
|
Parser.prototype._parseSignature = function(data) {
|
|
113589
|
-
let 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 !==
|
|
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
|
|
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 =
|
|
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 &
|
|
113679
|
-
color: Boolean(colorType &
|
|
113680
|
-
alpha: Boolean(colorType &
|
|
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 ===
|
|
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 ===
|
|
113752
|
+
if (this._colorType === constants3.COLORTYPE_GRAYSCALE) {
|
|
113719
113753
|
this.transColor([data.readUInt16BE(0)]);
|
|
113720
113754
|
}
|
|
113721
|
-
if (this._colorType ===
|
|
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) /
|
|
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 ===
|
|
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
|
|
114269
|
+
var constants3 = require_constants7();
|
|
114236
114270
|
module2.exports = function(dataIn, width, height, options) {
|
|
114237
|
-
let outHasAlpha = [
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
114336
|
-
case
|
|
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
|
|
114354
|
-
case
|
|
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
|
|
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 :
|
|
114541
|
-
options.inputColorType = typeof options.inputColorType === "number" ? options.inputColorType :
|
|
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
|
-
|
|
114544
|
-
|
|
114545
|
-
|
|
114546
|
-
|
|
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
|
-
|
|
114554
|
-
|
|
114555
|
-
|
|
114556
|
-
|
|
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 =
|
|
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 *
|
|
114601
|
-
return this._packChunk(
|
|
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(
|
|
114646
|
+
return this._packChunk(constants3.TYPE_IHDR, buf);
|
|
114613
114647
|
};
|
|
114614
114648
|
Packer.prototype.packIDAT = function(data) {
|
|
114615
|
-
return this._packChunk(
|
|
114649
|
+
return this._packChunk(constants3.TYPE_IDAT, data);
|
|
114616
114650
|
};
|
|
114617
114651
|
Packer.prototype.packIEND = function() {
|
|
114618
|
-
return this._packChunk(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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));
|
|
@@ -120682,11 +120716,19 @@ var init_codex_pty_runner = __esm({
|
|
|
120682
120716
|
onStatusChange;
|
|
120683
120717
|
onPhaseChange;
|
|
120684
120718
|
onReady;
|
|
120685
|
-
//
|
|
120686
|
-
//
|
|
120719
|
+
// Every Codex prompt the client can answer — startup gates (directory trust,
|
|
120720
|
+
// hooks review), command approvals, and the rate-limit model picker — is
|
|
120721
|
+
// broadcast through this one channel; null dismisses the card once the prompt
|
|
120722
|
+
// leaves the screen.
|
|
120723
|
+
//
|
|
120724
|
+
// Deliberately NOT onLiveQuestion/onLiveQuestionGone, which is Claude's
|
|
120725
|
+
// AskUserQuestion transport. Both channels land on the same mobile
|
|
120726
|
+
// QuestionCard, and the permission one is the correct fit for Codex: its menus
|
|
120727
|
+
// are answered by the option's real on-screen number (parseCodexNumberedOptions
|
|
120728
|
+
// emits `answerKeys: "2\r"`), which is exactly what `permissionIndices` carries
|
|
120729
|
+
// and what AskUserQuestion's down-arrow-count model cannot express. Wiring the
|
|
120730
|
+
// question channel as well would be a second path to the same card.
|
|
120687
120731
|
onPermissionChange;
|
|
120688
|
-
onLiveQuestion;
|
|
120689
|
-
onLiveQuestionGone;
|
|
120690
120732
|
onUserMessage;
|
|
120691
120733
|
log;
|
|
120692
120734
|
// Tracks sessions whose PTY has spawned but Codex hasn't yet reached its
|
|
@@ -120736,8 +120778,6 @@ var init_codex_pty_runner = __esm({
|
|
|
120736
120778
|
this.onPhaseChange = options.onPhaseChange;
|
|
120737
120779
|
this.onReady = options.onReady;
|
|
120738
120780
|
this.onPermissionChange = options.onPermissionChange;
|
|
120739
|
-
this.onLiveQuestion = options.onLiveQuestion;
|
|
120740
|
-
this.onLiveQuestionGone = options.onLiveQuestionGone;
|
|
120741
120781
|
this.onUserMessage = options.onUserMessage;
|
|
120742
120782
|
this.log = options.logger ?? getLogger("codex-pty");
|
|
120743
120783
|
}
|
|
@@ -122888,6 +122928,7 @@ var init_live_session_manager = __esm({
|
|
|
122888
122928
|
"use strict";
|
|
122889
122929
|
import_path28 = require("path");
|
|
122890
122930
|
init_codex_pty_runner();
|
|
122931
|
+
init_platform();
|
|
122891
122932
|
init_providers();
|
|
122892
122933
|
init_remote_session_runner();
|
|
122893
122934
|
init_pty_manager();
|
|
@@ -122920,11 +122961,13 @@ var init_live_session_manager = __esm({
|
|
|
122920
122961
|
async start(sessionId, options) {
|
|
122921
122962
|
const provider = options.provider ?? CLAUDE_CODE_PROVIDER;
|
|
122922
122963
|
const runner = this.assertSupportedProvider(provider, options.projectPath);
|
|
122964
|
+
this.assertProviderInstalled(provider);
|
|
122923
122965
|
return runner.start(sessionId, options);
|
|
122924
122966
|
}
|
|
122925
122967
|
async startFresh(options) {
|
|
122926
122968
|
const provider = options.provider ?? CLAUDE_CODE_PROVIDER;
|
|
122927
122969
|
const runner = this.assertSupportedProvider(provider, options.projectPath);
|
|
122970
|
+
this.assertProviderInstalled(provider);
|
|
122928
122971
|
return runner.startFresh(options);
|
|
122929
122972
|
}
|
|
122930
122973
|
/**
|
|
@@ -122943,6 +122986,7 @@ var init_live_session_manager = __esm({
|
|
|
122943
122986
|
err.statusCode = 501;
|
|
122944
122987
|
throw err;
|
|
122945
122988
|
}
|
|
122989
|
+
this.assertProviderInstalled(provider);
|
|
122946
122990
|
return runner.startFork(options);
|
|
122947
122991
|
}
|
|
122948
122992
|
sendInput(sessionId, input) {
|
|
@@ -123024,6 +123068,30 @@ var init_live_session_manager = __esm({
|
|
|
123024
123068
|
}
|
|
123025
123069
|
throw new Error(`Session not found: ${sessionId}`);
|
|
123026
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
|
+
}
|
|
123027
123095
|
assertSupportedProvider(provider, projectPath) {
|
|
123028
123096
|
if (this.remoteRunner) return this.remoteRunner;
|
|
123029
123097
|
const runner = this.runners.get(provider);
|
|
@@ -126357,10 +126425,10 @@ var require_truncate = __commonJS({
|
|
|
126357
126425
|
"node_modules/semver/functions/truncate.js"(exports2, module2) {
|
|
126358
126426
|
"use strict";
|
|
126359
126427
|
var parse3 = require_parse5();
|
|
126360
|
-
var
|
|
126428
|
+
var constants3 = require_constants8();
|
|
126361
126429
|
var SemVer = require_semver();
|
|
126362
126430
|
var truncate = (version2, truncation, options) => {
|
|
126363
|
-
if (!
|
|
126431
|
+
if (!constants3.RELEASE_TYPES.includes(truncation)) {
|
|
126364
126432
|
return null;
|
|
126365
126433
|
}
|
|
126366
126434
|
const clonedVersion = cloneInputVersion(version2, options);
|
|
@@ -127409,7 +127477,7 @@ var require_semver2 = __commonJS({
|
|
|
127409
127477
|
"node_modules/semver/index.js"(exports2, module2) {
|
|
127410
127478
|
"use strict";
|
|
127411
127479
|
var internalRe = require_re();
|
|
127412
|
-
var
|
|
127480
|
+
var constants3 = require_constants8();
|
|
127413
127481
|
var SemVer = require_semver();
|
|
127414
127482
|
var identifiers = require_identifiers();
|
|
127415
127483
|
var parse3 = require_parse5();
|
|
@@ -127493,8 +127561,8 @@ var require_semver2 = __commonJS({
|
|
|
127493
127561
|
re: internalRe.re,
|
|
127494
127562
|
src: internalRe.src,
|
|
127495
127563
|
tokens: internalRe.t,
|
|
127496
|
-
SEMVER_SPEC_VERSION:
|
|
127497
|
-
RELEASE_TYPES:
|
|
127564
|
+
SEMVER_SPEC_VERSION: constants3.SEMVER_SPEC_VERSION,
|
|
127565
|
+
RELEASE_TYPES: constants3.RELEASE_TYPES,
|
|
127498
127566
|
compareIdentifiers: identifiers.compareIdentifiers,
|
|
127499
127567
|
rcompareIdentifiers: identifiers.rcompareIdentifiers
|
|
127500
127568
|
};
|
|
@@ -134493,7 +134561,9 @@ var corsMiddleware = (configValue) => {
|
|
|
134493
134561
|
// src/api/middleware/error.middleware.ts
|
|
134494
134562
|
var errorMiddleware = (err, c) => {
|
|
134495
134563
|
const message = err instanceof Error ? err.message : "Internal server error";
|
|
134496
|
-
|
|
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);
|
|
134497
134567
|
};
|
|
134498
134568
|
|
|
134499
134569
|
// src/api/routes/backup.routes.ts
|
|
@@ -134918,6 +134988,7 @@ var createDeviceRoutes = (deps) => {
|
|
|
134918
134988
|
// src/api/routes/diagnostics.routes.ts
|
|
134919
134989
|
var import_fs3 = require("fs");
|
|
134920
134990
|
init_platform();
|
|
134991
|
+
init_providers();
|
|
134921
134992
|
|
|
134922
134993
|
// src/services/diagnostics/diagnostics.ts
|
|
134923
134994
|
var DIAGNOSTICS_CONTRACT_VERSION = 1;
|
|
@@ -135039,24 +135110,26 @@ function computeBootToken() {
|
|
|
135039
135110
|
}
|
|
135040
135111
|
|
|
135041
135112
|
// src/api/routes/diagnostics.routes.ts
|
|
135042
|
-
function providerCheck(name
|
|
135113
|
+
function providerCheck(name) {
|
|
135043
135114
|
try {
|
|
135044
|
-
const exe =
|
|
135045
|
-
|
|
135046
|
-
|
|
135047
|
-
|
|
135048
|
-
|
|
135049
|
-
|
|
135050
|
-
|
|
135051
|
-
|
|
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
|
+
}
|
|
135052
135125
|
} catch {
|
|
135053
|
-
return {
|
|
135054
|
-
id: `provider:${name}`,
|
|
135055
|
-
status: "failed",
|
|
135056
|
-
summary: `${name} CLI could not be located. Sessions for this provider cannot start.`,
|
|
135057
|
-
remediation: "PROVIDER_NOT_INSTALLED"
|
|
135058
|
-
};
|
|
135059
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
|
+
};
|
|
135060
135133
|
}
|
|
135061
135134
|
var createDiagnosticsRoutes = (deps) => {
|
|
135062
135135
|
const app = new Hono2();
|
|
@@ -135069,8 +135142,8 @@ var createDiagnosticsRoutes = (deps) => {
|
|
|
135069
135142
|
remediation: "NONE",
|
|
135070
135143
|
detail: { version: getVersion(), uptimeSeconds: Math.floor(process.uptime()) }
|
|
135071
135144
|
});
|
|
135072
|
-
checks.push(providerCheck(
|
|
135073
|
-
checks.push(providerCheck(
|
|
135145
|
+
checks.push(providerCheck(CLAUDE_CODE_PROVIDER));
|
|
135146
|
+
checks.push(providerCheck(CODEX_CLI_PROVIDER));
|
|
135074
135147
|
const cacheAlert = deps.cacheMonitor()?.healthzField();
|
|
135075
135148
|
checks.push(
|
|
135076
135149
|
cacheAlert ? {
|
|
@@ -136187,7 +136260,6 @@ var createProjectRoutes = (deps) => {
|
|
|
136187
136260
|
};
|
|
136188
136261
|
|
|
136189
136262
|
// src/api/routes/providers.routes.ts
|
|
136190
|
-
init_platform();
|
|
136191
136263
|
init_providers();
|
|
136192
136264
|
|
|
136193
136265
|
// src/services/providers/providerHealth.ts
|
|
@@ -136232,7 +136304,10 @@ function parseVersionOutput(output) {
|
|
|
136232
136304
|
const match2 = output.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
136233
136305
|
return match2 ? match2[0] : null;
|
|
136234
136306
|
}
|
|
136307
|
+
var versionByExe = /* @__PURE__ */ new Map();
|
|
136235
136308
|
function runVersion(exe) {
|
|
136309
|
+
const cached4 = versionByExe.get(exe);
|
|
136310
|
+
if (cached4 !== void 0) return Promise.resolve(cached4);
|
|
136236
136311
|
const viaShell = isWindows && /\.(?:cmd|bat)$/i.test(exe);
|
|
136237
136312
|
const file2 = viaShell ? `"${exe}"` : exe;
|
|
136238
136313
|
return new Promise((resolve4) => {
|
|
@@ -136242,7 +136317,9 @@ function runVersion(exe) {
|
|
|
136242
136317
|
{ timeout: VERSION_TIMEOUT_MS, shell: viaShell, windowsHide: true },
|
|
136243
136318
|
(err, stdout2, stderr) => {
|
|
136244
136319
|
if (err && !stdout2 && !stderr) return resolve4(null);
|
|
136245
|
-
|
|
136320
|
+
const version2 = parseVersionOutput(`${stdout2}${stderr}`);
|
|
136321
|
+
if (version2 !== null) versionByExe.set(exe, version2);
|
|
136322
|
+
resolve4(version2);
|
|
136246
136323
|
}
|
|
136247
136324
|
);
|
|
136248
136325
|
});
|
|
@@ -136286,13 +136363,16 @@ function compareSemver(a, b2) {
|
|
|
136286
136363
|
if (pb2.pre === null) return -1;
|
|
136287
136364
|
return pa.pre < pb2.pre ? -1 : 1;
|
|
136288
136365
|
}
|
|
136289
|
-
async function providerHealth(name,
|
|
136366
|
+
async function providerHealth(name, locateExe = () => locateProviderExe(name), detect = runVersion) {
|
|
136290
136367
|
const verifiedAgainst = VERIFIED_AGAINST[name];
|
|
136291
136368
|
const capabilities = capabilitiesFor(name);
|
|
136292
|
-
let exe;
|
|
136369
|
+
let exe = null;
|
|
136293
136370
|
try {
|
|
136294
|
-
exe =
|
|
136371
|
+
exe = locateExe();
|
|
136295
136372
|
} catch {
|
|
136373
|
+
exe = null;
|
|
136374
|
+
}
|
|
136375
|
+
if (exe === null) {
|
|
136296
136376
|
return {
|
|
136297
136377
|
name,
|
|
136298
136378
|
available: false,
|
|
@@ -136329,8 +136409,8 @@ var createProviderRoutes = () => {
|
|
|
136329
136409
|
const app = new Hono2();
|
|
136330
136410
|
app.get("/", async (c) => {
|
|
136331
136411
|
const providers = await Promise.all([
|
|
136332
|
-
providerHealth(CLAUDE_CODE_PROVIDER
|
|
136333
|
-
providerHealth(CODEX_CLI_PROVIDER
|
|
136412
|
+
providerHealth(CLAUDE_CODE_PROVIDER),
|
|
136413
|
+
providerHealth(CODEX_CLI_PROVIDER)
|
|
136334
136414
|
]);
|
|
136335
136415
|
return c.json({ providers });
|
|
136336
136416
|
});
|
|
@@ -148301,7 +148381,10 @@ var SessionHandlers = class {
|
|
|
148301
148381
|
});
|
|
148302
148382
|
this.sessionStore.addManaged(session);
|
|
148303
148383
|
this.registryBoot.recordSessionSpawn(session);
|
|
148304
|
-
const { outcome } = await this.deps.waitForStartupOutcome(
|
|
148384
|
+
const { outcome, session: settled } = await this.deps.waitForStartupOutcome(
|
|
148385
|
+
session.id,
|
|
148386
|
+
START_READY_TIMEOUT_MS
|
|
148387
|
+
);
|
|
148305
148388
|
const current = this.sessionStore.get(session.id, this.deps.ptyAttachedIds());
|
|
148306
148389
|
if (outcome === "ready" && current) {
|
|
148307
148390
|
json2(res, 200, { session: current });
|
|
@@ -148309,7 +148392,7 @@ var SessionHandlers = class {
|
|
|
148309
148392
|
json2(res, 502, {
|
|
148310
148393
|
id: session.id,
|
|
148311
148394
|
status: "idle",
|
|
148312
|
-
error:
|
|
148395
|
+
error: settled?.failureReason ?? "Session exited before becoming ready"
|
|
148313
148396
|
});
|
|
148314
148397
|
} else {
|
|
148315
148398
|
json2(res, 202, { id: session.id, status: "pending" });
|
|
@@ -148323,11 +148406,16 @@ var SessionHandlers = class {
|
|
|
148323
148406
|
} catch (err) {
|
|
148324
148407
|
const message = err instanceof Error ? err.message : "Failed to start session";
|
|
148325
148408
|
const statusCode = typeof err.statusCode === "number" ? err.statusCode : 500;
|
|
148409
|
+
const code = err.code;
|
|
148326
148410
|
this.log.error(`[start] failed to start session: ${message}`, {
|
|
148327
148411
|
event: "session.start_failed",
|
|
148328
148412
|
error: message
|
|
148329
148413
|
});
|
|
148330
|
-
json2(
|
|
148414
|
+
json2(
|
|
148415
|
+
res,
|
|
148416
|
+
statusCode,
|
|
148417
|
+
typeof code === "string" ? { error: message, code } : { error: message }
|
|
148418
|
+
);
|
|
148331
148419
|
}
|
|
148332
148420
|
}
|
|
148333
148421
|
async handleSetSessionName(sessionId, req, res) {
|
|
@@ -149023,7 +149111,37 @@ var PairTokenStore = class {
|
|
|
149023
149111
|
expiresInSeconds: Math.floor(this.ttlMs / 1e3)
|
|
149024
149112
|
};
|
|
149025
149113
|
}
|
|
149114
|
+
/**
|
|
149115
|
+
* Whether `consume` would succeed right now, WITHOUT spending the token.
|
|
149116
|
+
*
|
|
149117
|
+
* Exists so a caller can reject a bad token before doing any work, and still
|
|
149118
|
+
* spend the token only once the work has succeeded. A pair token is
|
|
149119
|
+
* single-use and lives 180 seconds, so spending it on a request that then
|
|
149120
|
+
* fails costs the user a whole new QR — and, worse, makes their retry
|
|
149121
|
+
* indistinguishable from an attacker replaying a photographed code, which is
|
|
149122
|
+
* the one signal `design.md` §2.6 designates as replay detection.
|
|
149123
|
+
*
|
|
149124
|
+
* Advisory, not a reservation: it takes no lock and holds nothing. The
|
|
149125
|
+
* authoritative answer is still `consume`'s.
|
|
149126
|
+
*/
|
|
149127
|
+
verify(token) {
|
|
149128
|
+
const result = this.check(token);
|
|
149129
|
+
return result.ok ? { ok: true } : result;
|
|
149130
|
+
}
|
|
149026
149131
|
consume(token) {
|
|
149132
|
+
const result = this.check(token);
|
|
149133
|
+
if (!result.ok) return result;
|
|
149134
|
+
result.record.used = true;
|
|
149135
|
+
return { ok: true };
|
|
149136
|
+
}
|
|
149137
|
+
/**
|
|
149138
|
+
* The shared predicate behind `verify` and `consume`.
|
|
149139
|
+
*
|
|
149140
|
+
* One implementation on purpose: two copies of "is this token usable" is two
|
|
149141
|
+
* places for the expiry or single-use rule to drift, and a drift in this
|
|
149142
|
+
* direction fails open.
|
|
149143
|
+
*/
|
|
149144
|
+
check(token) {
|
|
149027
149145
|
const record3 = this.current;
|
|
149028
149146
|
if (!record3 || record3.token !== token) return { ok: false, reason: "unknown" };
|
|
149029
149147
|
if (Date.now() > record3.expiresAt) {
|
|
@@ -149031,8 +149149,7 @@ var PairTokenStore = class {
|
|
|
149031
149149
|
return { ok: false, reason: "expired" };
|
|
149032
149150
|
}
|
|
149033
149151
|
if (record3.used) return { ok: false, reason: "used" };
|
|
149034
|
-
|
|
149035
|
-
return { ok: true };
|
|
149152
|
+
return { ok: true, record: record3 };
|
|
149036
149153
|
}
|
|
149037
149154
|
peek() {
|
|
149038
149155
|
return this.current;
|
|
@@ -149053,6 +149170,7 @@ var PairTokenStore = class {
|
|
|
149053
149170
|
};
|
|
149054
149171
|
|
|
149055
149172
|
// src/server.ts
|
|
149173
|
+
init_platform();
|
|
149056
149174
|
init_providers();
|
|
149057
149175
|
init_remote_session_runner();
|
|
149058
149176
|
|
|
@@ -150115,7 +150233,15 @@ function createLiveSessionOptions(deps) {
|
|
|
150115
150233
|
// grace-timer/idle-reaper hold (statusSource "shutdown") apart from a
|
|
150116
150234
|
// genuine process exit ("process-exit"), and reports both as
|
|
150117
150235
|
// `lifecycle: "completed"`. See managedToResponse in session-store.ts.
|
|
150118
|
-
...session.statusSource != null && { statusSource: session.statusSource }
|
|
150236
|
+
...session.statusSource != null && { statusSource: session.statusSource },
|
|
150237
|
+
// Why a session died, not just that it did. Without this the store's
|
|
150238
|
+
// copy has no failureReason, so managedToResponse falls through to
|
|
150239
|
+
// `lifecycle: "completed"` (see session-store.ts) and a session that
|
|
150240
|
+
// never started — missing CLI, missing project dir — is reported to
|
|
150241
|
+
// every client as one that finished normally. Guarded like its
|
|
150242
|
+
// neighbours: a later transition must not blank a recorded failure.
|
|
150243
|
+
...session.failureReason != null && { failureReason: session.failureReason },
|
|
150244
|
+
...session.failureCode != null && { failureCode: session.failureCode }
|
|
150119
150245
|
});
|
|
150120
150246
|
deps.managedSessionsRepo()?.recordStatus(
|
|
150121
150247
|
session.id,
|
|
@@ -153614,6 +153740,41 @@ var StreamerServer = class {
|
|
|
153614
153740
|
json2(res, 503, body);
|
|
153615
153741
|
return true;
|
|
153616
153742
|
}
|
|
153743
|
+
/**
|
|
153744
|
+
* Say which provider CLIs this machine can actually launch.
|
|
153745
|
+
*
|
|
153746
|
+
* The operator cannot discover this case unaided: under launchd/Task
|
|
153747
|
+
* Scheduler the service inherits a stripped PATH, so a CLI that works
|
|
153748
|
+
* perfectly in their terminal is invisible to the service, and every session
|
|
153749
|
+
* start dies milliseconds in. `/api/diagnostics` answers it too, but only for
|
|
153750
|
+
* someone who already suspects it.
|
|
153751
|
+
*
|
|
153752
|
+
* Availability only, never a version — `--version` costs a process spawn per
|
|
153753
|
+
* provider (85ms for claude here) and belongs on the first request that wants
|
|
153754
|
+
* it, not on boot.
|
|
153755
|
+
*
|
|
153756
|
+
* Called AFTER the port is bound, which is not cosmetic. This is the first
|
|
153757
|
+
* caller of the exe resolvers in the process, so the memo is cold by
|
|
153758
|
+
* definition and each provider pays one synchronous `which` / `where.exe`
|
|
153759
|
+
* (platform.ts) with a 3s timeout. On POSIX that is 3ms found, 7ms missing.
|
|
153760
|
+
* Windows is the risk — `where.exe` is slower, `execFileSync` blocks the
|
|
153761
|
+
* event loop, and Task Scheduler's stripped PATH is exactly where a miss
|
|
153762
|
+
* pays the full timeout — so the worst case is ~6s of two blocking lookups.
|
|
153763
|
+
* After `listen()` that delays the first requests on a box that cannot start
|
|
153764
|
+
* a session anyway; before it, it would have delayed binding the port.
|
|
153765
|
+
*/
|
|
153766
|
+
logProviderAvailability() {
|
|
153767
|
+
for (const provider of [CLAUDE_CODE_PROVIDER, CODEX_CLI_PROVIDER]) {
|
|
153768
|
+
if (locateProviderExe(provider)) {
|
|
153769
|
+
this.log.info(`Provider ${provider}: found`, { event: "config.provider", provider });
|
|
153770
|
+
} else {
|
|
153771
|
+
this.log.warn(`Provider ${provider}: not found on PATH \u2014 sessions cannot start`, {
|
|
153772
|
+
event: "config.provider_missing",
|
|
153773
|
+
provider
|
|
153774
|
+
});
|
|
153775
|
+
}
|
|
153776
|
+
}
|
|
153777
|
+
}
|
|
153617
153778
|
async listen(port, opts) {
|
|
153618
153779
|
if (this.featureFlags.ptyHost) {
|
|
153619
153780
|
try {
|
|
@@ -153674,6 +153835,7 @@ var StreamerServer = class {
|
|
|
153674
153835
|
event: "server.listening",
|
|
153675
153836
|
...this.host !== void 0 && { host: this.host }
|
|
153676
153837
|
});
|
|
153838
|
+
this.logProviderAvailability();
|
|
153677
153839
|
try {
|
|
153678
153840
|
this.runtimeStore = RuntimeStore.open(this.runtimeDbPath);
|
|
153679
153841
|
this.managedSessionsRepo = new ManagedSessionsRepository(this.runtimeStore.getDatabase());
|
|
@@ -154050,9 +154212,9 @@ var StreamerServer = class {
|
|
|
154050
154212
|
json2(res, 400, { error: "Missing token or clientPublicKey" });
|
|
154051
154213
|
return;
|
|
154052
154214
|
}
|
|
154053
|
-
const
|
|
154054
|
-
if (!
|
|
154055
|
-
json2(res, 401, { error: `Pair token ${
|
|
154215
|
+
const precheck = this.pairTokens.verify(token);
|
|
154216
|
+
if (!precheck.ok) {
|
|
154217
|
+
json2(res, 401, { error: `Pair token ${precheck.reason}` });
|
|
154056
154218
|
return;
|
|
154057
154219
|
}
|
|
154058
154220
|
let sealed;
|
|
@@ -154063,6 +154225,11 @@ var StreamerServer = class {
|
|
|
154063
154225
|
json2(res, 400, { error: message });
|
|
154064
154226
|
return;
|
|
154065
154227
|
}
|
|
154228
|
+
const result = this.pairTokens.consume(token);
|
|
154229
|
+
if (!result.ok) {
|
|
154230
|
+
json2(res, 401, { error: `Pair token ${result.reason}` });
|
|
154231
|
+
return;
|
|
154232
|
+
}
|
|
154066
154233
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
154067
154234
|
this.log.info(`[pair] token exchanged from ${ip} at ${ts2}`, {
|
|
154068
154235
|
event: "pair.token_exchanged",
|