billion-context 0.1.67 → 0.1.68-pr.428.255
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/README.md +69 -0
- package/dist/index.js +840 -400
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +51 -10
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1141,14 +1141,14 @@ var require_util = __commonJS({
|
|
|
1141
1141
|
}
|
|
1142
1142
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
1143
1143
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
1144
|
-
let
|
|
1144
|
+
let path17 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
1145
1145
|
if (origin[origin.length - 1] === "/") {
|
|
1146
1146
|
origin = origin.slice(0, origin.length - 1);
|
|
1147
1147
|
}
|
|
1148
|
-
if (
|
|
1149
|
-
|
|
1148
|
+
if (path17 && path17[0] !== "/") {
|
|
1149
|
+
path17 = `/${path17}`;
|
|
1150
1150
|
}
|
|
1151
|
-
return new URL(`${origin}${
|
|
1151
|
+
return new URL(`${origin}${path17}`);
|
|
1152
1152
|
}
|
|
1153
1153
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
1154
1154
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -1969,9 +1969,9 @@ var require_diagnostics = __commonJS({
|
|
|
1969
1969
|
"undici:client:sendHeaders",
|
|
1970
1970
|
(evt) => {
|
|
1971
1971
|
const {
|
|
1972
|
-
request: { method, path:
|
|
1972
|
+
request: { method, path: path17, origin }
|
|
1973
1973
|
} = evt;
|
|
1974
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
1974
|
+
debugLog("sending request to %s %s%s", method, origin, path17);
|
|
1975
1975
|
}
|
|
1976
1976
|
);
|
|
1977
1977
|
}
|
|
@@ -1989,14 +1989,14 @@ var require_diagnostics = __commonJS({
|
|
|
1989
1989
|
"undici:request:headers",
|
|
1990
1990
|
(evt) => {
|
|
1991
1991
|
const {
|
|
1992
|
-
request: { method, path:
|
|
1992
|
+
request: { method, path: path17, origin },
|
|
1993
1993
|
response: { statusCode }
|
|
1994
1994
|
} = evt;
|
|
1995
1995
|
debugLog(
|
|
1996
1996
|
"received response to %s %s%s - HTTP %d",
|
|
1997
1997
|
method,
|
|
1998
1998
|
origin,
|
|
1999
|
-
|
|
1999
|
+
path17,
|
|
2000
2000
|
statusCode
|
|
2001
2001
|
);
|
|
2002
2002
|
}
|
|
@@ -2005,23 +2005,23 @@ var require_diagnostics = __commonJS({
|
|
|
2005
2005
|
"undici:request:trailers",
|
|
2006
2006
|
(evt) => {
|
|
2007
2007
|
const {
|
|
2008
|
-
request: { method, path:
|
|
2008
|
+
request: { method, path: path17, origin }
|
|
2009
2009
|
} = evt;
|
|
2010
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
2010
|
+
debugLog("trailers received from %s %s%s", method, origin, path17);
|
|
2011
2011
|
}
|
|
2012
2012
|
);
|
|
2013
2013
|
diagnosticsChannel.subscribe(
|
|
2014
2014
|
"undici:request:error",
|
|
2015
2015
|
(evt) => {
|
|
2016
2016
|
const {
|
|
2017
|
-
request: { method, path:
|
|
2017
|
+
request: { method, path: path17, origin },
|
|
2018
2018
|
error
|
|
2019
2019
|
} = evt;
|
|
2020
2020
|
debugLog(
|
|
2021
2021
|
"request to %s %s%s errored - %s",
|
|
2022
2022
|
method,
|
|
2023
2023
|
origin,
|
|
2024
|
-
|
|
2024
|
+
path17,
|
|
2025
2025
|
error.message
|
|
2026
2026
|
);
|
|
2027
2027
|
}
|
|
@@ -2136,7 +2136,7 @@ var require_request = __commonJS({
|
|
|
2136
2136
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
2137
2137
|
var Request = class {
|
|
2138
2138
|
constructor(origin, {
|
|
2139
|
-
path:
|
|
2139
|
+
path: path17,
|
|
2140
2140
|
method,
|
|
2141
2141
|
body,
|
|
2142
2142
|
headers,
|
|
@@ -2153,11 +2153,11 @@ var require_request = __commonJS({
|
|
|
2153
2153
|
maxRedirections,
|
|
2154
2154
|
typeOfService
|
|
2155
2155
|
}, handler) {
|
|
2156
|
-
if (typeof
|
|
2156
|
+
if (typeof path17 !== "string") {
|
|
2157
2157
|
throw new InvalidArgumentError("path must be a string");
|
|
2158
|
-
} else if (
|
|
2158
|
+
} else if (path17[0] !== "/" && !(path17.startsWith("http://") || path17.startsWith("https://")) && method !== "CONNECT") {
|
|
2159
2159
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
2160
|
-
} else if (invalidPathRegex.test(
|
|
2160
|
+
} else if (invalidPathRegex.test(path17)) {
|
|
2161
2161
|
throw new InvalidArgumentError("invalid request path");
|
|
2162
2162
|
}
|
|
2163
2163
|
if (typeof method !== "string") {
|
|
@@ -2232,7 +2232,7 @@ var require_request = __commonJS({
|
|
|
2232
2232
|
this.completed = false;
|
|
2233
2233
|
this.aborted = false;
|
|
2234
2234
|
this.upgrade = upgrade || null;
|
|
2235
|
-
this.path = query ? serializePathWithQuery(
|
|
2235
|
+
this.path = query ? serializePathWithQuery(path17, query) : path17;
|
|
2236
2236
|
this.origin = origin;
|
|
2237
2237
|
this.protocol = getProtocolFromUrlString(origin);
|
|
2238
2238
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -7415,7 +7415,7 @@ var require_client_h1 = __commonJS({
|
|
|
7415
7415
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
7416
7416
|
}
|
|
7417
7417
|
function writeH1(client, request) {
|
|
7418
|
-
const { method, path:
|
|
7418
|
+
const { method, path: path17, host, upgrade, blocking, reset } = request;
|
|
7419
7419
|
let { body, headers, contentLength } = request;
|
|
7420
7420
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
7421
7421
|
if (util.isFormDataLike(body)) {
|
|
@@ -7493,7 +7493,7 @@ var require_client_h1 = __commonJS({
|
|
|
7493
7493
|
if (socket.setTypeOfService) {
|
|
7494
7494
|
socket.setTypeOfService(request.typeOfService);
|
|
7495
7495
|
}
|
|
7496
|
-
let header = `${method} ${
|
|
7496
|
+
let header = `${method} ${path17} HTTP/1.1\r
|
|
7497
7497
|
`;
|
|
7498
7498
|
if (typeof host === "string") {
|
|
7499
7499
|
header += `host: ${host}\r
|
|
@@ -8146,7 +8146,7 @@ var require_client_h2 = __commonJS({
|
|
|
8146
8146
|
function writeH2(client, request) {
|
|
8147
8147
|
const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
|
|
8148
8148
|
const session = client[kHTTP2Session];
|
|
8149
|
-
const { method, path:
|
|
8149
|
+
const { method, path: path17, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
|
|
8150
8150
|
let { body } = request;
|
|
8151
8151
|
if (upgrade != null && upgrade !== "websocket") {
|
|
8152
8152
|
util.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -8214,7 +8214,7 @@ var require_client_h2 = __commonJS({
|
|
|
8214
8214
|
}
|
|
8215
8215
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
8216
8216
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
8217
|
-
headers[HTTP2_HEADER_PATH] =
|
|
8217
|
+
headers[HTTP2_HEADER_PATH] = path17;
|
|
8218
8218
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
8219
8219
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
8220
8220
|
} else {
|
|
@@ -8255,7 +8255,7 @@ var require_client_h2 = __commonJS({
|
|
|
8255
8255
|
stream2.setTimeout(requestTimeout);
|
|
8256
8256
|
return true;
|
|
8257
8257
|
}
|
|
8258
|
-
headers[HTTP2_HEADER_PATH] =
|
|
8258
|
+
headers[HTTP2_HEADER_PATH] = path17;
|
|
8259
8259
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
8260
8260
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
8261
8261
|
if (body && typeof body.read === "function") {
|
|
@@ -10598,10 +10598,10 @@ var require_proxy_agent = __commonJS({
|
|
|
10598
10598
|
};
|
|
10599
10599
|
const {
|
|
10600
10600
|
origin,
|
|
10601
|
-
path:
|
|
10601
|
+
path: path17 = "/",
|
|
10602
10602
|
headers = {}
|
|
10603
10603
|
} = opts;
|
|
10604
|
-
opts.path = origin +
|
|
10604
|
+
opts.path = origin + path17;
|
|
10605
10605
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
10606
10606
|
const { host } = new URL(origin);
|
|
10607
10607
|
headers.host = host;
|
|
@@ -12684,20 +12684,20 @@ var require_mock_utils = __commonJS({
|
|
|
12684
12684
|
}
|
|
12685
12685
|
return normalizedQp;
|
|
12686
12686
|
}
|
|
12687
|
-
function safeUrl(
|
|
12688
|
-
if (typeof
|
|
12689
|
-
return
|
|
12687
|
+
function safeUrl(path17) {
|
|
12688
|
+
if (typeof path17 !== "string") {
|
|
12689
|
+
return path17;
|
|
12690
12690
|
}
|
|
12691
|
-
const pathSegments =
|
|
12691
|
+
const pathSegments = path17.split("?", 3);
|
|
12692
12692
|
if (pathSegments.length !== 2) {
|
|
12693
|
-
return
|
|
12693
|
+
return path17;
|
|
12694
12694
|
}
|
|
12695
12695
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
12696
12696
|
qp.sort();
|
|
12697
12697
|
return [...pathSegments, qp.toString()].join("?");
|
|
12698
12698
|
}
|
|
12699
|
-
function matchKey(mockDispatch2, { path:
|
|
12700
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
12699
|
+
function matchKey(mockDispatch2, { path: path17, method, body, headers }) {
|
|
12700
|
+
const pathMatch = matchValue(mockDispatch2.path, path17);
|
|
12701
12701
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
12702
12702
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
12703
12703
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -12722,8 +12722,8 @@ var require_mock_utils = __commonJS({
|
|
|
12722
12722
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
12723
12723
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
12724
12724
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
12725
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
12726
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
12725
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path17, ignoreTrailingSlash }) => {
|
|
12726
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path17)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path17), resolvedPath);
|
|
12727
12727
|
});
|
|
12728
12728
|
if (matchedMockDispatches.length === 0) {
|
|
12729
12729
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -12762,19 +12762,19 @@ var require_mock_utils = __commonJS({
|
|
|
12762
12762
|
mockDispatches.splice(index, 1);
|
|
12763
12763
|
}
|
|
12764
12764
|
}
|
|
12765
|
-
function removeTrailingSlash(
|
|
12766
|
-
while (
|
|
12767
|
-
|
|
12765
|
+
function removeTrailingSlash(path17) {
|
|
12766
|
+
while (path17.endsWith("/")) {
|
|
12767
|
+
path17 = path17.slice(0, -1);
|
|
12768
12768
|
}
|
|
12769
|
-
if (
|
|
12770
|
-
|
|
12769
|
+
if (path17.length === 0) {
|
|
12770
|
+
path17 = "/";
|
|
12771
12771
|
}
|
|
12772
|
-
return
|
|
12772
|
+
return path17;
|
|
12773
12773
|
}
|
|
12774
12774
|
function buildKey(opts) {
|
|
12775
|
-
const { path:
|
|
12775
|
+
const { path: path17, method, body, headers, query } = opts;
|
|
12776
12776
|
return {
|
|
12777
|
-
path:
|
|
12777
|
+
path: path17,
|
|
12778
12778
|
method,
|
|
12779
12779
|
body,
|
|
12780
12780
|
headers,
|
|
@@ -13464,10 +13464,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
13464
13464
|
}
|
|
13465
13465
|
format(pendingInterceptors) {
|
|
13466
13466
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
13467
|
-
({ method, path:
|
|
13467
|
+
({ method, path: path17, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
13468
13468
|
Method: method,
|
|
13469
13469
|
Origin: origin,
|
|
13470
|
-
Path:
|
|
13470
|
+
Path: path17,
|
|
13471
13471
|
"Status code": statusCode,
|
|
13472
13472
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
13473
13473
|
Invocations: timesInvoked,
|
|
@@ -13549,9 +13549,9 @@ var require_mock_agent = __commonJS({
|
|
|
13549
13549
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
13550
13550
|
const dispatchOpts = { ...opts };
|
|
13551
13551
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
13552
|
-
const [
|
|
13552
|
+
const [path17, searchParams] = dispatchOpts.path.split("?");
|
|
13553
13553
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
13554
|
-
dispatchOpts.path = `${
|
|
13554
|
+
dispatchOpts.path = `${path17}?${normalizedSearchParams}`;
|
|
13555
13555
|
}
|
|
13556
13556
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
13557
13557
|
}
|
|
@@ -13952,12 +13952,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13952
13952
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
13953
13953
|
*/
|
|
13954
13954
|
async loadSnapshots(filePath) {
|
|
13955
|
-
const
|
|
13956
|
-
if (!
|
|
13955
|
+
const path17 = filePath || this.#snapshotPath;
|
|
13956
|
+
if (!path17) {
|
|
13957
13957
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
13958
13958
|
}
|
|
13959
13959
|
try {
|
|
13960
|
-
const data = await readFile3(resolve(
|
|
13960
|
+
const data = await readFile3(resolve(path17), "utf8");
|
|
13961
13961
|
const parsed = JSON.parse(data);
|
|
13962
13962
|
if (Array.isArray(parsed)) {
|
|
13963
13963
|
this.#snapshots.clear();
|
|
@@ -13971,7 +13971,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13971
13971
|
if (error.code === "ENOENT") {
|
|
13972
13972
|
this.#snapshots.clear();
|
|
13973
13973
|
} else {
|
|
13974
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
13974
|
+
throw new UndiciError(`Failed to load snapshots from ${path17}`, { cause: error });
|
|
13975
13975
|
}
|
|
13976
13976
|
}
|
|
13977
13977
|
}
|
|
@@ -13982,11 +13982,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13982
13982
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
13983
13983
|
*/
|
|
13984
13984
|
async saveSnapshots(filePath) {
|
|
13985
|
-
const
|
|
13986
|
-
if (!
|
|
13985
|
+
const path17 = filePath || this.#snapshotPath;
|
|
13986
|
+
if (!path17) {
|
|
13987
13987
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
13988
13988
|
}
|
|
13989
|
-
const resolvedPath = resolve(
|
|
13989
|
+
const resolvedPath = resolve(path17);
|
|
13990
13990
|
await mkdir3(dirname5(resolvedPath), { recursive: true });
|
|
13991
13991
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
13992
13992
|
hash,
|
|
@@ -14618,15 +14618,15 @@ var require_redirect_handler = __commonJS({
|
|
|
14618
14618
|
return;
|
|
14619
14619
|
}
|
|
14620
14620
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
14621
|
-
const
|
|
14622
|
-
const redirectUrlString = `${origin}${
|
|
14621
|
+
const path17 = search ? `${pathname}${search}` : pathname;
|
|
14622
|
+
const redirectUrlString = `${origin}${path17}`;
|
|
14623
14623
|
for (const historyUrl of this.history) {
|
|
14624
14624
|
if (historyUrl.toString() === redirectUrlString) {
|
|
14625
14625
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
14626
14626
|
}
|
|
14627
14627
|
}
|
|
14628
14628
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
14629
|
-
this.opts.path =
|
|
14629
|
+
this.opts.path = path17;
|
|
14630
14630
|
this.opts.origin = origin;
|
|
14631
14631
|
this.opts.query = null;
|
|
14632
14632
|
}
|
|
@@ -14903,7 +14903,7 @@ var require_dns = __commonJS({
|
|
|
14903
14903
|
"node_modules/undici/lib/interceptor/dns.js"(exports, module) {
|
|
14904
14904
|
"use strict";
|
|
14905
14905
|
var { isIP } = __require("net");
|
|
14906
|
-
var { lookup } = __require("dns");
|
|
14906
|
+
var { lookup: lookup2 } = __require("dns");
|
|
14907
14907
|
var DecoratorHandler = require_decorator_handler();
|
|
14908
14908
|
var { InvalidArgumentError, InformationalError } = require_errors();
|
|
14909
14909
|
var maxInt = Math.pow(2, 31) - 1;
|
|
@@ -15093,7 +15093,7 @@ var require_dns = __commonJS({
|
|
|
15093
15093
|
}
|
|
15094
15094
|
}
|
|
15095
15095
|
#defaultLookup(origin, opts, cb) {
|
|
15096
|
-
|
|
15096
|
+
lookup2(
|
|
15097
15097
|
origin.hostname,
|
|
15098
15098
|
{
|
|
15099
15099
|
all: true,
|
|
@@ -16395,10 +16395,10 @@ var require_cache_handler = __commonJS({
|
|
|
16395
16395
|
}
|
|
16396
16396
|
return locationUrl.pathname + locationUrl.search;
|
|
16397
16397
|
}
|
|
16398
|
-
function deleteCachedUri(store, cacheKey,
|
|
16398
|
+
function deleteCachedUri(store, cacheKey, path17) {
|
|
16399
16399
|
deleteCachedValue(store, {
|
|
16400
16400
|
...cacheKey,
|
|
16401
|
-
path:
|
|
16401
|
+
path: path17
|
|
16402
16402
|
});
|
|
16403
16403
|
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
16404
16404
|
const method = util.safeHTTPMethods[i];
|
|
@@ -16406,7 +16406,7 @@ var require_cache_handler = __commonJS({
|
|
|
16406
16406
|
deleteCachedValue(store, {
|
|
16407
16407
|
...cacheKey,
|
|
16408
16408
|
method,
|
|
16409
|
-
path:
|
|
16409
|
+
path: path17
|
|
16410
16410
|
});
|
|
16411
16411
|
}
|
|
16412
16412
|
}
|
|
@@ -16417,9 +16417,9 @@ var require_cache_handler = __commonJS({
|
|
|
16417
16417
|
}
|
|
16418
16418
|
const values = Array.isArray(headerValue3) ? headerValue3 : [headerValue3];
|
|
16419
16419
|
for (let i = 0; i < values.length; i++) {
|
|
16420
|
-
const
|
|
16421
|
-
if (
|
|
16422
|
-
deleteCachedUri(store, cacheKey,
|
|
16420
|
+
const path17 = getSameOriginPath(cacheKey, values[i]);
|
|
16421
|
+
if (path17 !== void 0) {
|
|
16422
|
+
deleteCachedUri(store, cacheKey, path17);
|
|
16423
16423
|
}
|
|
16424
16424
|
}
|
|
16425
16425
|
}
|
|
@@ -21297,11 +21297,11 @@ var require_fetch = __commonJS({
|
|
|
21297
21297
|
function dispatch({ body }) {
|
|
21298
21298
|
const url = requestCurrentURL(request);
|
|
21299
21299
|
const agent = fetchParams.controller.dispatcher;
|
|
21300
|
-
const
|
|
21300
|
+
const path17 = url.pathname + url.search;
|
|
21301
21301
|
const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
|
|
21302
21302
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
21303
21303
|
{
|
|
21304
|
-
path: hasTrailingQuestionMark ? `${
|
|
21304
|
+
path: hasTrailingQuestionMark ? `${path17}?` : path17,
|
|
21305
21305
|
origin: url.origin,
|
|
21306
21306
|
method: request.method,
|
|
21307
21307
|
body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body,
|
|
@@ -22248,9 +22248,9 @@ var require_util4 = __commonJS({
|
|
|
22248
22248
|
}
|
|
22249
22249
|
}
|
|
22250
22250
|
}
|
|
22251
|
-
function validateCookiePath(
|
|
22252
|
-
for (let i = 0; i <
|
|
22253
|
-
const code =
|
|
22251
|
+
function validateCookiePath(path17) {
|
|
22252
|
+
for (let i = 0; i < path17.length; ++i) {
|
|
22253
|
+
const code = path17.charCodeAt(i);
|
|
22254
22254
|
if (code < 32 || // exclude CTLs (0-31)
|
|
22255
22255
|
code > 126 || // exclude DEL and non-ascii
|
|
22256
22256
|
code === 59) {
|
|
@@ -25487,11 +25487,11 @@ var require_undici = __commonJS({
|
|
|
25487
25487
|
if (typeof opts.path !== "string") {
|
|
25488
25488
|
throw new InvalidArgumentError("invalid opts.path");
|
|
25489
25489
|
}
|
|
25490
|
-
let
|
|
25490
|
+
let path17 = opts.path;
|
|
25491
25491
|
if (!opts.path.startsWith("/")) {
|
|
25492
|
-
|
|
25492
|
+
path17 = `/${path17}`;
|
|
25493
25493
|
}
|
|
25494
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
25494
|
+
url = new URL(util.parseOrigin(url).origin + path17);
|
|
25495
25495
|
} else {
|
|
25496
25496
|
if (!opts) {
|
|
25497
25497
|
opts = typeof url === "object" ? url : {};
|
|
@@ -47033,9 +47033,6 @@ function stateDir() {
|
|
|
47033
47033
|
function defaultLogFile() {
|
|
47034
47034
|
return path.join(stateDir(), "bili.log");
|
|
47035
47035
|
}
|
|
47036
|
-
function proxyOriginFile() {
|
|
47037
|
-
return path.join(stateDir(), "proxy-origin");
|
|
47038
|
-
}
|
|
47039
47036
|
function caDir() {
|
|
47040
47037
|
return path.join(dataDir(), "ca");
|
|
47041
47038
|
}
|
|
@@ -47622,13 +47619,13 @@ function getUpstreamConnectionStatus() {
|
|
|
47622
47619
|
}
|
|
47623
47620
|
|
|
47624
47621
|
// src/config.ts
|
|
47625
|
-
function safeReadJson(
|
|
47622
|
+
function safeReadJson(path17) {
|
|
47626
47623
|
try {
|
|
47627
|
-
const raw = readFileSync(
|
|
47624
|
+
const raw = readFileSync(path17, "utf8").replace(/^\uFEFF/, "");
|
|
47628
47625
|
return JSON.parse(raw);
|
|
47629
47626
|
} catch (e) {
|
|
47630
47627
|
if (e.code !== "ENOENT") {
|
|
47631
|
-
log("error", `[acp-config] failed to parse ${
|
|
47628
|
+
log("error", `[acp-config] failed to parse ${path17}: ${String(e)}`);
|
|
47632
47629
|
}
|
|
47633
47630
|
return void 0;
|
|
47634
47631
|
}
|
|
@@ -47908,8 +47905,8 @@ function rejectLegacyRoute(key, value) {
|
|
|
47908
47905
|
|
|
47909
47906
|
// src/server.ts
|
|
47910
47907
|
import http from "http";
|
|
47911
|
-
import
|
|
47912
|
-
import { randomUUID as
|
|
47908
|
+
import fs7 from "fs";
|
|
47909
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
47913
47910
|
|
|
47914
47911
|
// src/compress-settings.ts
|
|
47915
47912
|
function resolveContextLimitValue(raw, nativeLimit) {
|
|
@@ -50158,15 +50155,11 @@ function resolveDecompress(args, ctx) {
|
|
|
50158
50155
|
body = view.text;
|
|
50159
50156
|
count = view.count;
|
|
50160
50157
|
} else {
|
|
50161
|
-
const collected = collectBlockContent(ctx.session.state, block, ctx.messages, { full });
|
|
50158
|
+
const collected = collectBlockContent(ctx.session.state, block, ctx.compressMessages ?? ctx.messages, { full });
|
|
50162
50159
|
body = collected.text || block.summary;
|
|
50163
50160
|
count = collected.count;
|
|
50164
50161
|
}
|
|
50165
|
-
|
|
50166
|
-
ctx.session.state = deactivateBlock(ctx.session.state, [blockId]);
|
|
50167
|
-
ctx.session.blockContents.delete(blockId);
|
|
50168
|
-
}
|
|
50169
|
-
const header = `[Restored block ${blockId} \u2014 ${count} item(s)${full ? ", full" : ""}]`;
|
|
50162
|
+
const header = `[Block ${blockId} content \u2014 ${count} item(s)${full ? ", full" : ""}]`;
|
|
50170
50163
|
const safeBlockId = blockId.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
50171
50164
|
const outPath = body.length > 1e4 ? join2(tmpdir(), `acp-decompress-${safeBlockId}-${Date.now()}.txt`) : null;
|
|
50172
50165
|
if (outPath) {
|
|
@@ -51151,6 +51144,140 @@ function reapOrphanBlocks(session, visible, deactivate) {
|
|
|
51151
51144
|
return { reaped };
|
|
51152
51145
|
}
|
|
51153
51146
|
|
|
51147
|
+
// src/instance.ts
|
|
51148
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
51149
|
+
import fs3 from "fs";
|
|
51150
|
+
import path7 from "path";
|
|
51151
|
+
function isProxyInstanceFile(v2) {
|
|
51152
|
+
return v2 !== void 0 && "instanceId" in v2;
|
|
51153
|
+
}
|
|
51154
|
+
function readProxyInstanceFile(file) {
|
|
51155
|
+
let raw;
|
|
51156
|
+
try {
|
|
51157
|
+
raw = fs3.readFileSync(file ?? instanceFilePath(), "utf8").trim();
|
|
51158
|
+
} catch {
|
|
51159
|
+
return void 0;
|
|
51160
|
+
}
|
|
51161
|
+
if (raw.startsWith("{")) {
|
|
51162
|
+
try {
|
|
51163
|
+
const parsed = JSON.parse(raw);
|
|
51164
|
+
if (typeof parsed.origin === "string" && /^https?:\/\/\S+$/.test(parsed.origin)) {
|
|
51165
|
+
const windows = {};
|
|
51166
|
+
if (parsed.modelWindows && typeof parsed.modelWindows === "object") {
|
|
51167
|
+
for (const [k2, v2] of Object.entries(parsed.modelWindows)) {
|
|
51168
|
+
const n = Number(v2);
|
|
51169
|
+
if (Number.isFinite(n) && n > 0) windows[k2] = n;
|
|
51170
|
+
}
|
|
51171
|
+
}
|
|
51172
|
+
return {
|
|
51173
|
+
origin: parsed.origin,
|
|
51174
|
+
instanceId: typeof parsed.instanceId === "string" ? parsed.instanceId : "",
|
|
51175
|
+
pid: typeof parsed.pid === "number" ? parsed.pid : 0,
|
|
51176
|
+
startedAt: typeof parsed.startedAt === "number" ? parsed.startedAt : 0,
|
|
51177
|
+
host: typeof parsed.host === "string" ? parsed.host : "",
|
|
51178
|
+
port: typeof parsed.port === "number" ? parsed.port : 0,
|
|
51179
|
+
passthrough: Boolean(parsed.passthrough),
|
|
51180
|
+
mitmDomains: Array.isArray(parsed.mitmDomains) ? parsed.mitmDomains.map(String) : [],
|
|
51181
|
+
modelWindows: windows,
|
|
51182
|
+
launchToken: typeof parsed.launchToken === "string" ? parsed.launchToken : void 0
|
|
51183
|
+
};
|
|
51184
|
+
}
|
|
51185
|
+
} catch {
|
|
51186
|
+
}
|
|
51187
|
+
}
|
|
51188
|
+
if (/^https?:\/\/\S+$/.test(raw)) return { origin: raw };
|
|
51189
|
+
return void 0;
|
|
51190
|
+
}
|
|
51191
|
+
function instanceFilePath() {
|
|
51192
|
+
return path7.join(stateDir(), "proxy-origin");
|
|
51193
|
+
}
|
|
51194
|
+
function atomicWriteInstanceFile(info, file) {
|
|
51195
|
+
const filePath = file ?? instanceFilePath();
|
|
51196
|
+
fs3.mkdirSync(path7.dirname(filePath), { recursive: true });
|
|
51197
|
+
const tempPath = `${filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
51198
|
+
let descriptor;
|
|
51199
|
+
try {
|
|
51200
|
+
descriptor = fs3.openSync(tempPath, "wx", 420);
|
|
51201
|
+
fs3.writeSync(descriptor, JSON.stringify(info) + "\n", null, "utf8");
|
|
51202
|
+
fs3.fsyncSync(descriptor);
|
|
51203
|
+
fs3.closeSync(descriptor);
|
|
51204
|
+
descriptor = void 0;
|
|
51205
|
+
fs3.renameSync(tempPath, filePath);
|
|
51206
|
+
} catch (error) {
|
|
51207
|
+
if (descriptor !== void 0) {
|
|
51208
|
+
try {
|
|
51209
|
+
fs3.closeSync(descriptor);
|
|
51210
|
+
} catch {
|
|
51211
|
+
}
|
|
51212
|
+
}
|
|
51213
|
+
try {
|
|
51214
|
+
fs3.unlinkSync(tempPath);
|
|
51215
|
+
} catch {
|
|
51216
|
+
}
|
|
51217
|
+
throw error;
|
|
51218
|
+
}
|
|
51219
|
+
}
|
|
51220
|
+
function clearProxyInstanceFile(instanceId, file) {
|
|
51221
|
+
const filePath = file ?? instanceFilePath();
|
|
51222
|
+
const current = readProxyInstanceFile(filePath);
|
|
51223
|
+
if (isProxyInstanceFile(current) && current.instanceId === instanceId) {
|
|
51224
|
+
try {
|
|
51225
|
+
fs3.unlinkSync(filePath);
|
|
51226
|
+
} catch {
|
|
51227
|
+
}
|
|
51228
|
+
}
|
|
51229
|
+
}
|
|
51230
|
+
function isPidAlive(pid) {
|
|
51231
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
51232
|
+
try {
|
|
51233
|
+
process.kill(pid, 0);
|
|
51234
|
+
return true;
|
|
51235
|
+
} catch (err2) {
|
|
51236
|
+
return err2.code === "EPERM";
|
|
51237
|
+
}
|
|
51238
|
+
}
|
|
51239
|
+
function registryFilePath() {
|
|
51240
|
+
return path7.join(stateDir(), "instances.json");
|
|
51241
|
+
}
|
|
51242
|
+
function registerInstanceAndWarn(entry, warn) {
|
|
51243
|
+
const file = registryFilePath();
|
|
51244
|
+
const entries = [];
|
|
51245
|
+
try {
|
|
51246
|
+
const parsed = JSON.parse(fs3.readFileSync(file, "utf8"));
|
|
51247
|
+
if (Array.isArray(parsed.instances)) {
|
|
51248
|
+
for (const e of parsed.instances) {
|
|
51249
|
+
if (e && typeof e.instanceId === "string" && e.instanceId !== entry.instanceId && isPidAlive(e.pid)) {
|
|
51250
|
+
entries.push(e);
|
|
51251
|
+
}
|
|
51252
|
+
}
|
|
51253
|
+
}
|
|
51254
|
+
} catch {
|
|
51255
|
+
}
|
|
51256
|
+
for (const other of entries) {
|
|
51257
|
+
warn(
|
|
51258
|
+
`another bili instance is running (pid ${other.pid}, ${other.origin}) \u2014 both processes will write the same sessions directory; stop one to avoid state pollution (#394)`
|
|
51259
|
+
);
|
|
51260
|
+
}
|
|
51261
|
+
entries.push(entry);
|
|
51262
|
+
try {
|
|
51263
|
+
fs3.mkdirSync(path7.dirname(file), { recursive: true });
|
|
51264
|
+
fs3.writeFileSync(file, JSON.stringify({ instances: entries }) + "\n");
|
|
51265
|
+
} catch {
|
|
51266
|
+
}
|
|
51267
|
+
}
|
|
51268
|
+
function unregisterInstance(instanceId) {
|
|
51269
|
+
const file = registryFilePath();
|
|
51270
|
+
try {
|
|
51271
|
+
const parsed = JSON.parse(fs3.readFileSync(file, "utf8"));
|
|
51272
|
+
if (!Array.isArray(parsed.instances)) return;
|
|
51273
|
+
const kept = parsed.instances.filter(
|
|
51274
|
+
(e) => !(e && typeof e.instanceId === "string" && e.instanceId === instanceId) && isPidAlive(e.pid)
|
|
51275
|
+
);
|
|
51276
|
+
fs3.writeFileSync(file, JSON.stringify({ instances: kept }) + "\n");
|
|
51277
|
+
} catch {
|
|
51278
|
+
}
|
|
51279
|
+
}
|
|
51280
|
+
|
|
51154
51281
|
// src/compress-loop.ts
|
|
51155
51282
|
function buildVisibilityMarker(toolName, result) {
|
|
51156
51283
|
const lines = result.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
@@ -51469,11 +51596,11 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
51469
51596
|
let newBody = adapter.buildRequest(coreMessages, systemPrompt, requestBody);
|
|
51470
51597
|
if (process.env.ACP_DUMP_BODY === "1") {
|
|
51471
51598
|
try {
|
|
51472
|
-
const
|
|
51599
|
+
const fs12 = await import("fs");
|
|
51473
51600
|
const dumpDir = process.env.ACP_DUMP_DIR || `${process.env.HOME}/.local/state/billion-context/dumps`;
|
|
51474
|
-
|
|
51601
|
+
fs12.mkdirSync(dumpDir, { recursive: true });
|
|
51475
51602
|
const sid = ctx.session.id ?? "unknown";
|
|
51476
|
-
|
|
51603
|
+
fs12.writeFileSync(`${dumpDir}/req-${Date.now()}-${sid}-REREQUEST.json`, JSON.stringify(newBody, null, 2));
|
|
51477
51604
|
} catch {
|
|
51478
51605
|
}
|
|
51479
51606
|
}
|
|
@@ -51591,25 +51718,18 @@ function reserveOutputHeadroom(window2, maxOutput) {
|
|
|
51591
51718
|
}
|
|
51592
51719
|
return window2;
|
|
51593
51720
|
}
|
|
51594
|
-
function
|
|
51595
|
-
let
|
|
51596
|
-
|
|
51597
|
-
|
|
51598
|
-
|
|
51599
|
-
|
|
51600
|
-
|
|
51601
|
-
|
|
51602
|
-
|
|
51603
|
-
|
|
51604
|
-
|
|
51605
|
-
|
|
51606
|
-
const rest = [];
|
|
51607
|
-
for (let i = lead; i < messages.length; i++) {
|
|
51608
|
-
const r = messages[i].role;
|
|
51609
|
-
if (r === "system" || r === "developer") mid.push(messages[i]);
|
|
51610
|
-
else rest.push(messages[i]);
|
|
51611
|
-
}
|
|
51612
|
-
return [...head, ...mid, ...rest];
|
|
51721
|
+
function systemToUser(messages) {
|
|
51722
|
+
let hasSys = false;
|
|
51723
|
+
for (const m2 of messages) {
|
|
51724
|
+
if (m2.role === "system" || m2.role === "developer") {
|
|
51725
|
+
hasSys = true;
|
|
51726
|
+
break;
|
|
51727
|
+
}
|
|
51728
|
+
}
|
|
51729
|
+
if (!hasSys) return messages;
|
|
51730
|
+
return messages.map(
|
|
51731
|
+
(m2) => m2.role === "system" || m2.role === "developer" ? { ...m2, role: "user" } : m2
|
|
51732
|
+
);
|
|
51613
51733
|
}
|
|
51614
51734
|
function shouldReserveOutputHeadroom(protocol) {
|
|
51615
51735
|
return protocol !== "anthropic";
|
|
@@ -52272,7 +52392,7 @@ function createOpenaiAdapter(requestBody, clientSystem) {
|
|
|
52272
52392
|
);
|
|
52273
52393
|
return {
|
|
52274
52394
|
buildRequest(coreMessages, systemPrompt, body) {
|
|
52275
|
-
const messages =
|
|
52395
|
+
const messages = systemToUser(coreToOpenai(coreMessages));
|
|
52276
52396
|
const withSys = injectOpenaiSystem(messages, [clientSystem, systemPrompt].filter((p2) => typeof p2 === "string" && p2.length > 0));
|
|
52277
52397
|
return { ...body, messages: withSys };
|
|
52278
52398
|
},
|
|
@@ -53630,13 +53750,13 @@ function buildStatusPanel(input) {
|
|
|
53630
53750
|
|
|
53631
53751
|
// src/plugin.ts
|
|
53632
53752
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
53633
|
-
import
|
|
53634
|
-
import
|
|
53753
|
+
import fs4 from "fs";
|
|
53754
|
+
import path8 from "path";
|
|
53635
53755
|
var PROXY_VERSION = (() => {
|
|
53636
53756
|
try {
|
|
53637
53757
|
const here = fileURLToPath2(import.meta.url);
|
|
53638
|
-
const pkg =
|
|
53639
|
-
return JSON.parse(
|
|
53758
|
+
const pkg = path8.join(path8.dirname(here), "..", "package.json");
|
|
53759
|
+
return JSON.parse(fs4.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
53640
53760
|
} catch {
|
|
53641
53761
|
return "dev";
|
|
53642
53762
|
}
|
|
@@ -53648,8 +53768,8 @@ var PLUGIN_PROTOCOL_VERSION = 1;
|
|
|
53648
53768
|
var VERSION = (() => {
|
|
53649
53769
|
try {
|
|
53650
53770
|
const here = fileURLToPath2(import.meta.url);
|
|
53651
|
-
const pkg =
|
|
53652
|
-
return JSON.parse(
|
|
53771
|
+
const pkg = path8.join(path8.dirname(here), "..", "package.json");
|
|
53772
|
+
return JSON.parse(fs4.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
53653
53773
|
} catch {
|
|
53654
53774
|
return "dev";
|
|
53655
53775
|
}
|
|
@@ -53678,14 +53798,20 @@ function pluginReportedContextWindow(headers) {
|
|
|
53678
53798
|
var MAX_PLUGIN_CONVERSATIONS = 1024;
|
|
53679
53799
|
var conversations = /* @__PURE__ */ new Map();
|
|
53680
53800
|
var remembered = /* @__PURE__ */ new Map();
|
|
53681
|
-
var conversationsFile = () =>
|
|
53801
|
+
var conversationsFile = () => path8.join(stateDir(), "plugin-conversations.json");
|
|
53682
53802
|
var conversationsSaveTimer;
|
|
53803
|
+
var conversationsDirty = false;
|
|
53683
53804
|
function writeConversationsFile() {
|
|
53805
|
+
if (!conversationsDirty) return;
|
|
53684
53806
|
try {
|
|
53685
53807
|
const obj = {};
|
|
53686
53808
|
for (const [k2, v2] of conversations) obj[k2] = v2;
|
|
53687
|
-
|
|
53688
|
-
|
|
53809
|
+
fs4.mkdirSync(stateDir(), { recursive: true });
|
|
53810
|
+
const filePath = conversationsFile();
|
|
53811
|
+
const draft = `${filePath}.${process.pid}.bili-tmp`;
|
|
53812
|
+
fs4.writeFileSync(draft, JSON.stringify(obj));
|
|
53813
|
+
fs4.renameSync(draft, filePath);
|
|
53814
|
+
conversationsDirty = false;
|
|
53689
53815
|
} catch {
|
|
53690
53816
|
}
|
|
53691
53817
|
}
|
|
@@ -53704,8 +53830,13 @@ function flushConversations() {
|
|
|
53704
53830
|
writeConversationsFile();
|
|
53705
53831
|
}
|
|
53706
53832
|
function loadConversations() {
|
|
53833
|
+
let raw;
|
|
53834
|
+
try {
|
|
53835
|
+
raw = fs4.readFileSync(conversationsFile(), "utf8");
|
|
53836
|
+
} catch {
|
|
53837
|
+
return;
|
|
53838
|
+
}
|
|
53707
53839
|
try {
|
|
53708
|
-
const raw = fs3.readFileSync(conversationsFile(), "utf8");
|
|
53709
53840
|
const obj = JSON.parse(raw);
|
|
53710
53841
|
for (const [k2, v2] of Object.entries(obj)) {
|
|
53711
53842
|
if (v2 && typeof v2.sessionId === "string" && v2.sessionId.length > 0) {
|
|
@@ -53713,11 +53844,18 @@ function loadConversations() {
|
|
|
53713
53844
|
}
|
|
53714
53845
|
}
|
|
53715
53846
|
} catch {
|
|
53847
|
+
try {
|
|
53848
|
+
fs4.renameSync(conversationsFile(), `${conversationsFile()}.corrupt-${Date.now()}`);
|
|
53849
|
+
} catch {
|
|
53850
|
+
}
|
|
53851
|
+
log("warn", "[plugin] plugin-conversations.json is corrupt \u2014 backed up beside the original, starting an empty routing table");
|
|
53716
53852
|
}
|
|
53853
|
+
conversationsDirty = false;
|
|
53717
53854
|
}
|
|
53718
53855
|
function recordPluginSession(conversationId2, sessionId) {
|
|
53719
53856
|
conversations.delete(conversationId2);
|
|
53720
53857
|
conversations.set(conversationId2, { sessionId, lastSeen: Date.now() });
|
|
53858
|
+
conversationsDirty = true;
|
|
53721
53859
|
if (conversations.size > MAX_PLUGIN_CONVERSATIONS) {
|
|
53722
53860
|
const oldest = conversations.keys().next().value;
|
|
53723
53861
|
if (oldest !== void 0) conversations.delete(oldest);
|
|
@@ -54167,14 +54305,14 @@ async function pipePluginJson(stream2, res, session, protocol) {
|
|
|
54167
54305
|
import tls3 from "tls";
|
|
54168
54306
|
|
|
54169
54307
|
// src/discover.ts
|
|
54170
|
-
import
|
|
54308
|
+
import fs6 from "fs";
|
|
54171
54309
|
import os2 from "os";
|
|
54172
|
-
import
|
|
54310
|
+
import path10 from "path";
|
|
54173
54311
|
|
|
54174
54312
|
// src/client-config.ts
|
|
54175
|
-
import
|
|
54313
|
+
import fs5 from "fs";
|
|
54176
54314
|
import os from "os";
|
|
54177
|
-
import
|
|
54315
|
+
import path9 from "path";
|
|
54178
54316
|
function toModelWindow(id, contextWindow) {
|
|
54179
54317
|
return typeof id === "string" && id.length > 0 && typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > 0 ? { id, contextWindow: Math.floor(contextWindow) } : null;
|
|
54180
54318
|
}
|
|
@@ -54183,7 +54321,7 @@ function nonEmpty2(s3) {
|
|
|
54183
54321
|
}
|
|
54184
54322
|
function readJsonObject(filePath) {
|
|
54185
54323
|
try {
|
|
54186
|
-
const txt =
|
|
54324
|
+
const txt = fs5.readFileSync(filePath, "utf8");
|
|
54187
54325
|
const parsed = JSON.parse(txt);
|
|
54188
54326
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
54189
54327
|
} catch {
|
|
@@ -54192,19 +54330,19 @@ function readJsonObject(filePath) {
|
|
|
54192
54330
|
}
|
|
54193
54331
|
function resolvePiHome(env) {
|
|
54194
54332
|
const h = os.homedir();
|
|
54195
|
-
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : nonEmpty2(env.PI_HOME) ? env.PI_HOME :
|
|
54333
|
+
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : nonEmpty2(env.PI_HOME) ? env.PI_HOME : path9.join(h, ".pi", "agent");
|
|
54196
54334
|
}
|
|
54197
54335
|
function resolveOmpHome(env) {
|
|
54198
54336
|
const h = os.homedir();
|
|
54199
|
-
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR :
|
|
54337
|
+
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : path9.join(h, ".omp", "agent");
|
|
54200
54338
|
}
|
|
54201
54339
|
function resolveHermesHome(env) {
|
|
54202
54340
|
const h = os.homedir();
|
|
54203
|
-
return nonEmpty2(env.HERMES_HOME) ? env.HERMES_HOME :
|
|
54341
|
+
return nonEmpty2(env.HERMES_HOME) ? env.HERMES_HOME : path9.join(h, ".hermes");
|
|
54204
54342
|
}
|
|
54205
54343
|
function resolveDshHome(env) {
|
|
54206
54344
|
const h = os.homedir();
|
|
54207
|
-
return nonEmpty2(env.DSH_HOME) ? env.DSH_HOME :
|
|
54345
|
+
return nonEmpty2(env.DSH_HOME) ? env.DSH_HOME : path9.join(h, ".dsh");
|
|
54208
54346
|
}
|
|
54209
54347
|
function parseDshSettingsYaml(text) {
|
|
54210
54348
|
const out = [];
|
|
@@ -54223,7 +54361,7 @@ function parseDshSettingsYaml(text) {
|
|
|
54223
54361
|
function readDshConfig(dshHome) {
|
|
54224
54362
|
let text;
|
|
54225
54363
|
try {
|
|
54226
|
-
text =
|
|
54364
|
+
text = fs5.readFileSync(path9.join(dshHome, "settings.yaml"), "utf8");
|
|
54227
54365
|
} catch {
|
|
54228
54366
|
return { baseUrls: [] };
|
|
54229
54367
|
}
|
|
@@ -54231,8 +54369,8 @@ function readDshConfig(dshHome) {
|
|
|
54231
54369
|
}
|
|
54232
54370
|
function readClaudeSettings(homeDir, cwd, env = process.env) {
|
|
54233
54371
|
const files = [
|
|
54234
|
-
|
|
54235
|
-
|
|
54372
|
+
path9.join(homeDir, ".claude", "settings.json"),
|
|
54373
|
+
path9.join(cwd, ".claude", "settings.json")
|
|
54236
54374
|
];
|
|
54237
54375
|
let anthropicBaseUrl;
|
|
54238
54376
|
let model;
|
|
@@ -54305,17 +54443,17 @@ function parseCodexToml(text) {
|
|
|
54305
54443
|
return result;
|
|
54306
54444
|
}
|
|
54307
54445
|
function readCodexConfig(codexHome) {
|
|
54308
|
-
const cfgPath =
|
|
54446
|
+
const cfgPath = path9.join(codexHome, "config.toml");
|
|
54309
54447
|
let text;
|
|
54310
54448
|
try {
|
|
54311
|
-
text =
|
|
54449
|
+
text = fs5.readFileSync(cfgPath, "utf8");
|
|
54312
54450
|
} catch {
|
|
54313
54451
|
return { providers: {} };
|
|
54314
54452
|
}
|
|
54315
54453
|
return parseCodexToml(text);
|
|
54316
54454
|
}
|
|
54317
54455
|
function readPiConfig(piHome) {
|
|
54318
|
-
const cfgPath =
|
|
54456
|
+
const cfgPath = path9.join(piHome, "models.json");
|
|
54319
54457
|
const obj = readJsonObject(cfgPath);
|
|
54320
54458
|
const providers = {};
|
|
54321
54459
|
const rawProviders = obj?.providers;
|
|
@@ -54396,10 +54534,10 @@ function parseOmpYaml(text) {
|
|
|
54396
54534
|
return result;
|
|
54397
54535
|
}
|
|
54398
54536
|
function readOmpConfig(ompHome) {
|
|
54399
|
-
const cfgPath =
|
|
54537
|
+
const cfgPath = path9.join(ompHome, "models.yml");
|
|
54400
54538
|
let text;
|
|
54401
54539
|
try {
|
|
54402
|
-
text =
|
|
54540
|
+
text = fs5.readFileSync(cfgPath, "utf8");
|
|
54403
54541
|
} catch {
|
|
54404
54542
|
return { providers: {} };
|
|
54405
54543
|
}
|
|
@@ -54472,10 +54610,10 @@ function parseHermesYaml(text) {
|
|
|
54472
54610
|
return result;
|
|
54473
54611
|
}
|
|
54474
54612
|
function readHermesConfig(hermesHome) {
|
|
54475
|
-
const cfgPath =
|
|
54613
|
+
const cfgPath = path9.join(hermesHome, "config.yaml");
|
|
54476
54614
|
let text;
|
|
54477
54615
|
try {
|
|
54478
|
-
text =
|
|
54616
|
+
text = fs5.readFileSync(cfgPath, "utf8");
|
|
54479
54617
|
} catch {
|
|
54480
54618
|
return { providers: {} };
|
|
54481
54619
|
}
|
|
@@ -54483,13 +54621,13 @@ function readHermesConfig(hermesHome) {
|
|
|
54483
54621
|
}
|
|
54484
54622
|
function resolveOpencodeConfigFile(env) {
|
|
54485
54623
|
if (nonEmpty2(env.OPENCODE_CONFIG)) return env.OPENCODE_CONFIG;
|
|
54486
|
-
const xdg2 = nonEmpty2(env.XDG_CONFIG_HOME) ? env.XDG_CONFIG_HOME :
|
|
54487
|
-
return
|
|
54624
|
+
const xdg2 = nonEmpty2(env.XDG_CONFIG_HOME) ? env.XDG_CONFIG_HOME : path9.join(os.homedir(), ".config");
|
|
54625
|
+
return path9.join(xdg2, "opencode", "opencode.json");
|
|
54488
54626
|
}
|
|
54489
54627
|
function readOpencodeConfig(file) {
|
|
54490
54628
|
let text;
|
|
54491
54629
|
try {
|
|
54492
|
-
text =
|
|
54630
|
+
text = fs5.readFileSync(file, "utf8");
|
|
54493
54631
|
} catch {
|
|
54494
54632
|
return { providers: {} };
|
|
54495
54633
|
}
|
|
@@ -54546,10 +54684,10 @@ function parseZcodeConfig(obj) {
|
|
|
54546
54684
|
return result;
|
|
54547
54685
|
}
|
|
54548
54686
|
function readZcodeConfig(zcodeHome) {
|
|
54549
|
-
const cfgPath =
|
|
54687
|
+
const cfgPath = path9.join(zcodeHome, "v2", "config.json");
|
|
54550
54688
|
let txt;
|
|
54551
54689
|
try {
|
|
54552
|
-
txt =
|
|
54690
|
+
txt = fs5.readFileSync(cfgPath, "utf8");
|
|
54553
54691
|
} catch {
|
|
54554
54692
|
return { providers: {} };
|
|
54555
54693
|
}
|
|
@@ -54565,10 +54703,10 @@ function loadClientConfig(env, cwd) {
|
|
|
54565
54703
|
const home = os.homedir();
|
|
54566
54704
|
const config = {};
|
|
54567
54705
|
config.claude = readClaudeSettings(home, cwd, env);
|
|
54568
|
-
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME :
|
|
54706
|
+
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path9.join(home, ".codex");
|
|
54569
54707
|
config.codex = readCodexConfig(codexHome);
|
|
54570
54708
|
config.pi = readPiConfig(resolvePiHome(env));
|
|
54571
|
-
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR :
|
|
54709
|
+
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path9.join(home, ".zcode");
|
|
54572
54710
|
config.zcode = readZcodeConfig(zcodeHome);
|
|
54573
54711
|
config.omp = readOmpConfig(resolveOmpHome(env));
|
|
54574
54712
|
config.opencode = readOpencodeConfig(resolveOpencodeConfigFile(env));
|
|
@@ -54628,21 +54766,21 @@ function extractHttpsHosts(config) {
|
|
|
54628
54766
|
}
|
|
54629
54767
|
function configFilePaths(env) {
|
|
54630
54768
|
const home = os2.homedir();
|
|
54631
|
-
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME :
|
|
54632
|
-
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR :
|
|
54769
|
+
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path10.join(home, ".codex");
|
|
54770
|
+
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path10.join(home, ".zcode");
|
|
54633
54771
|
return [
|
|
54634
|
-
|
|
54635
|
-
|
|
54636
|
-
|
|
54637
|
-
|
|
54638
|
-
|
|
54772
|
+
path10.join(home, ".claude", "settings.json"),
|
|
54773
|
+
path10.join(process.cwd(), ".claude", "settings.json"),
|
|
54774
|
+
path10.join(codexHome, "config.toml"),
|
|
54775
|
+
path10.join(resolvePiHome(env), "models.json"),
|
|
54776
|
+
path10.join(zcodeHome, "v2", "config.json")
|
|
54639
54777
|
];
|
|
54640
54778
|
}
|
|
54641
54779
|
function readMtimes(paths) {
|
|
54642
54780
|
const mtimes = /* @__PURE__ */ new Map();
|
|
54643
54781
|
for (const p2 of paths) {
|
|
54644
54782
|
try {
|
|
54645
|
-
const st2 =
|
|
54783
|
+
const st2 = fs6.statSync(p2);
|
|
54646
54784
|
mtimes.set(p2, st2.mtimeMs);
|
|
54647
54785
|
} catch {
|
|
54648
54786
|
}
|
|
@@ -54810,6 +54948,108 @@ function readMitmUpstream(socket) {
|
|
|
54810
54948
|
return socket[MITM_UPSTREAM_KEY];
|
|
54811
54949
|
}
|
|
54812
54950
|
|
|
54951
|
+
// src/tunnel-guard.ts
|
|
54952
|
+
import { lookup } from "dns/promises";
|
|
54953
|
+
import { networkInterfaces } from "os";
|
|
54954
|
+
var BILI_TUNNEL_HEADER = "x-bili-tunnel";
|
|
54955
|
+
function parseIpLiteral(s3) {
|
|
54956
|
+
const t = s3.trim().toLowerCase();
|
|
54957
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(t)) return t;
|
|
54958
|
+
if (t.includes(":")) return t;
|
|
54959
|
+
return null;
|
|
54960
|
+
}
|
|
54961
|
+
function classifyIp(ip) {
|
|
54962
|
+
const lit = parseIpLiteral(ip);
|
|
54963
|
+
if (!lit) return "public";
|
|
54964
|
+
if (lit.includes(":")) {
|
|
54965
|
+
if (lit === "::1" || lit === "::") return "loopback";
|
|
54966
|
+
const mapped = lit.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
54967
|
+
if (mapped) return classifyIp(mapped[1]);
|
|
54968
|
+
if (lit.startsWith("fe8") || lit.startsWith("fe9") || lit.startsWith("fea") || lit.startsWith("feb")) return "linkLocal";
|
|
54969
|
+
if (lit.startsWith("fc") || lit.startsWith("fd")) return "private";
|
|
54970
|
+
return "public";
|
|
54971
|
+
}
|
|
54972
|
+
const parts = lit.split(".").map(Number);
|
|
54973
|
+
const [a, b2] = parts;
|
|
54974
|
+
if (a === 127) return "loopback";
|
|
54975
|
+
if (a === 169 && b2 === 254) return "linkLocal";
|
|
54976
|
+
if (a === 10 || a === 0) return "private";
|
|
54977
|
+
if (a === 172 && b2 >= 16 && b2 <= 31) return "private";
|
|
54978
|
+
if (a === 192 && b2 === 168) return "private";
|
|
54979
|
+
if (a === 100 && b2 >= 64 && b2 <= 127) return "private";
|
|
54980
|
+
return "public";
|
|
54981
|
+
}
|
|
54982
|
+
var dnsResolveHost = async (host) => {
|
|
54983
|
+
const res = await lookup(host, { all: true, family: 0 });
|
|
54984
|
+
return res.map((r) => r.address);
|
|
54985
|
+
};
|
|
54986
|
+
var localAddrCache;
|
|
54987
|
+
function localMachineIps() {
|
|
54988
|
+
const now = Date.now();
|
|
54989
|
+
if (!localAddrCache || now - localAddrCache.at > 3e4) {
|
|
54990
|
+
const ips = /* @__PURE__ */ new Set(["127.0.0.1", "::1"]);
|
|
54991
|
+
for (const list of Object.values(networkInterfaces())) {
|
|
54992
|
+
for (const ni2 of list ?? []) {
|
|
54993
|
+
if (ni2.address) ips.add(ni2.address.toLowerCase());
|
|
54994
|
+
}
|
|
54995
|
+
}
|
|
54996
|
+
for (let i = 0; i <= 255; i++) ips.add(`127.0.0.${i}`);
|
|
54997
|
+
localAddrCache = { at: now, ips };
|
|
54998
|
+
}
|
|
54999
|
+
return localAddrCache.ips;
|
|
55000
|
+
}
|
|
55001
|
+
function allowlistHit(host, port, allowlist) {
|
|
55002
|
+
const h = host.toLowerCase();
|
|
55003
|
+
const hp = `${h}:${port}`;
|
|
55004
|
+
return allowlist.some((e) => e === h || e === hp);
|
|
55005
|
+
}
|
|
55006
|
+
async function checkTunnelDestination(origin, ctx) {
|
|
55007
|
+
let u2;
|
|
55008
|
+
try {
|
|
55009
|
+
u2 = new URL(origin);
|
|
55010
|
+
} catch {
|
|
55011
|
+
return { ok: false, code: "unresolvable", message: `invalid tunnel destination ${origin}` };
|
|
55012
|
+
}
|
|
55013
|
+
const host = u2.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
55014
|
+
const port = u2.port ? Number(u2.port) : u2.protocol === "https:" ? 443 : 80;
|
|
55015
|
+
let ips;
|
|
55016
|
+
const literal = parseIpLiteral(host);
|
|
55017
|
+
if (literal) {
|
|
55018
|
+
ips = [literal];
|
|
55019
|
+
} else {
|
|
55020
|
+
try {
|
|
55021
|
+
ips = await (ctx.resolveHost ?? dnsResolveHost)(host);
|
|
55022
|
+
} catch {
|
|
55023
|
+
return { ok: false, code: "unresolvable", message: `cannot resolve tunnel destination ${host}` };
|
|
55024
|
+
}
|
|
55025
|
+
if (ips.length === 0) return { ok: false, code: "unresolvable", message: `no addresses for tunnel destination ${host}` };
|
|
55026
|
+
}
|
|
55027
|
+
if (ctx.selfPort !== void 0 && port === ctx.selfPort) {
|
|
55028
|
+
const mine = (ctx.localIps ?? localMachineIps)();
|
|
55029
|
+
if (ips.some((ip) => mine.has(ip.toLowerCase()) || mine.has(`::ffff:${ip.toLowerCase()}`))) {
|
|
55030
|
+
return { ok: false, code: "self", message: "the bili tunnel may not target the proxy itself" };
|
|
55031
|
+
}
|
|
55032
|
+
}
|
|
55033
|
+
const classes = ips.map((ip) => classifyIp(ip));
|
|
55034
|
+
if (classes.includes("linkLocal")) {
|
|
55035
|
+
return { ok: false, code: "linkLocal", message: "link-local / metadata destinations are blocked from the bili tunnel" };
|
|
55036
|
+
}
|
|
55037
|
+
if (!classes.every((c) => c === "public")) {
|
|
55038
|
+
if (ctx.clientLoopback) return { ok: true };
|
|
55039
|
+
if (allowlistHit(host, port, ctx.allowlist)) return { ok: true };
|
|
55040
|
+
return {
|
|
55041
|
+
ok: false,
|
|
55042
|
+
code: "privateRemote",
|
|
55043
|
+
message: `tunnel destination ${host} resolves to a loopback/private address; remote clients may only reach it via BILI_TUNNEL_ALLOWED_HOSTS`
|
|
55044
|
+
};
|
|
55045
|
+
}
|
|
55046
|
+
return { ok: true };
|
|
55047
|
+
}
|
|
55048
|
+
function tunnelAllowlistFromEnv(env = process.env) {
|
|
55049
|
+
const raw = env.BILI_TUNNEL_ALLOWED_HOSTS ?? "";
|
|
55050
|
+
return raw.split(",").map((s3) => s3.trim().toLowerCase()).filter((s3) => s3.length > 0);
|
|
55051
|
+
}
|
|
55052
|
+
|
|
54813
55053
|
// src/content-encoding.ts
|
|
54814
55054
|
import { promisify } from "util";
|
|
54815
55055
|
import { brotliDecompress, gunzip, inflate, inflateRaw } from "zlib";
|
|
@@ -55652,7 +55892,7 @@ function resolveUpstream(_opts, reqUrl, req) {
|
|
|
55652
55892
|
if (rest.startsWith("http://") || rest.startsWith("https://")) {
|
|
55653
55893
|
try {
|
|
55654
55894
|
const u2 = new URL(rest);
|
|
55655
|
-
return { upstream: `${u2.protocol}//${u2.host}`, rewrittenUrl: rest, explicitProtocol };
|
|
55895
|
+
return { upstream: `${u2.protocol}//${u2.host}`, rewrittenUrl: rest, explicitProtocol, tunnel: true };
|
|
55656
55896
|
} catch {
|
|
55657
55897
|
}
|
|
55658
55898
|
}
|
|
@@ -55664,17 +55904,20 @@ async function startServer(opts) {
|
|
|
55664
55904
|
const core = createCore();
|
|
55665
55905
|
const config = opts.kernelConfig;
|
|
55666
55906
|
const log2 = (level, msg) => logMsg(opts, level, msg);
|
|
55667
|
-
const instanceId =
|
|
55907
|
+
const instanceId = randomUUID4();
|
|
55908
|
+
const instanceStartedAt = Date.now();
|
|
55668
55909
|
await initSessions();
|
|
55669
55910
|
loadConversations();
|
|
55670
55911
|
log2("info", `[persist] ${getStore().enabled ? "enabled" : "disabled"}`);
|
|
55912
|
+
const tunnelAllowlist = tunnelAllowlistFromEnv();
|
|
55913
|
+
if (tunnelAllowlist.length > 0) log2("info", `[tunnel] remote-client allowlist: ${tunnelAllowlist.join(", ")}`);
|
|
55671
55914
|
if (filePath) {
|
|
55672
55915
|
log2("info", `[log] writing to ${filePath}`);
|
|
55673
55916
|
}
|
|
55674
55917
|
void loadRegistry();
|
|
55675
55918
|
const server = http.createServer(async (req, res) => {
|
|
55676
55919
|
try {
|
|
55677
|
-
await handle(req, res, opts, core, config, log2, instanceId);
|
|
55920
|
+
await handle(req, res, opts, core, config, log2, instanceId, instanceStartedAt);
|
|
55678
55921
|
} catch (err2) {
|
|
55679
55922
|
const msg = String(err2);
|
|
55680
55923
|
log2("error", msg);
|
|
@@ -55705,33 +55948,65 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
55705
55948
|
const allowRemoteConnect = opts.host === "0.0.0.0" || opts.host === "::" || !isLoopbackAddress(opts.host);
|
|
55706
55949
|
setupMitm(server, opts.mitm.domains, (msg) => log2("info", msg), (host) => resolveProxy(opts.routes, opts.proxy, `https://${host}`, opts.proxyFallback), allowRemoteConnect);
|
|
55707
55950
|
}
|
|
55708
|
-
|
|
55951
|
+
const launchToken = process.env.BILI_LAUNCH_TOKEN?.trim();
|
|
55952
|
+
const MAX_LISTEN_ATTEMPTS = 17;
|
|
55953
|
+
let listenAttempts = 0;
|
|
55954
|
+
let lastTriedPort = opts.port;
|
|
55955
|
+
const announceListening = () => {
|
|
55956
|
+
const actualPort = server.address() === null ? opts.port : server.address().port;
|
|
55709
55957
|
const nonLoopbackBind = opts.host === "0.0.0.0" || opts.host === "::" || !isLoopbackAddress(opts.host);
|
|
55710
55958
|
const displayHost = nonLoopbackBind ? opts.host : opts.host === "0.0.0.0" ? "localhost" : opts.host;
|
|
55959
|
+
const originHost = opts.host === "0.0.0.0" || opts.host === "::" || opts.host === "localhost" ? "127.0.0.1" : opts.host.includes(":") && !opts.host.startsWith("[") ? `[${opts.host}]` : opts.host;
|
|
55960
|
+
const origin = `http://${originHost}:${actualPort}`;
|
|
55711
55961
|
try {
|
|
55712
|
-
|
|
55713
|
-
|
|
55714
|
-
|
|
55715
|
-
|
|
55962
|
+
fs7.mkdirSync(stateDir(), { recursive: true });
|
|
55963
|
+
atomicWriteInstanceFile({
|
|
55964
|
+
origin,
|
|
55965
|
+
instanceId,
|
|
55966
|
+
pid: process.pid,
|
|
55967
|
+
startedAt: instanceStartedAt,
|
|
55968
|
+
host: opts.host,
|
|
55969
|
+
port: actualPort,
|
|
55970
|
+
passthrough: opts.passthrough,
|
|
55971
|
+
mitmDomains: opts.mitm.enabled ? opts.mitm.domains : [],
|
|
55972
|
+
modelWindows: { ...LAUNCHER_MODEL_WINDOWS },
|
|
55973
|
+
launchToken: launchToken || void 0
|
|
55974
|
+
});
|
|
55716
55975
|
} catch {
|
|
55717
55976
|
}
|
|
55977
|
+
registerInstanceAndWarn(
|
|
55978
|
+
{ instanceId, pid: process.pid, port: actualPort, origin, startedAt: instanceStartedAt },
|
|
55979
|
+
(msg) => log2("warn", `[instances] ${msg}`)
|
|
55980
|
+
);
|
|
55718
55981
|
const nOverrides = Object.keys(opts.routes).length;
|
|
55719
55982
|
log2(
|
|
55720
55983
|
"info",
|
|
55721
|
-
`acp-proxy listening on http://${displayHost}:${
|
|
55984
|
+
`acp-proxy listening on http://${displayHost}:${actualPort} \u2014 web UI: http://${displayHost}:${actualPort}/__bili/ \u2014 zero-config: prefix any baseURL with http://${displayHost}:${actualPort}/bili/` + (nOverrides ? ` \u2014 context overrides for ${nOverrides} upstream URL(s)` : "") + (opts.mitm.enabled ? ` \u2014 MITM proxy on (whitelist)${opts.mitm.domains.length ? ` +${opts.mitm.domains.join(",")}` : ""}` : "")
|
|
55722
55985
|
);
|
|
55723
55986
|
if (nonLoopbackBind) {
|
|
55724
55987
|
log2(
|
|
55725
55988
|
"warn",
|
|
55726
|
-
`[security] bound to ${opts.host} \u2014 proxy endpoints (/bili/, CONNECT for whitelisted model hosts) are reachable from the network with NO authentication; /__bili/ management endpoints stay loopback-only. Restrict access with a firewall on untrusted networks. Remote agents: point baseURL at http://<this-host>:${
|
|
55989
|
+
`[security] bound to ${opts.host} \u2014 proxy endpoints (/bili/, CONNECT for whitelisted model hosts) are reachable from the network with NO authentication; /__bili/ management endpoints stay loopback-only. Restrict access with a firewall on untrusted networks. Remote agents: point baseURL at http://<this-host>:${actualPort}/bili/`
|
|
55727
55990
|
);
|
|
55728
55991
|
}
|
|
55729
55992
|
if (opts.debug) {
|
|
55730
55993
|
log2("info", `[debug] build features: raw-HTTP-capture(on) | remote_compaction_v2-strip(on) | cert-MITM-launcher(on) | strip-acp-summary(on) \u2014 seeing this line confirms the launcher build (not registry 0.1.34)`);
|
|
55731
55994
|
}
|
|
55732
|
-
}
|
|
55995
|
+
};
|
|
55996
|
+
const attemptListen = (port) => {
|
|
55997
|
+
lastTriedPort = port;
|
|
55998
|
+
server.listen(port, opts.host, announceListening);
|
|
55999
|
+
};
|
|
56000
|
+
attemptListen(opts.port);
|
|
55733
56001
|
server.on("error", (err2) => {
|
|
55734
|
-
|
|
56002
|
+
if (err2.code === "EADDRINUSE" && launchToken && listenAttempts < MAX_LISTEN_ATTEMPTS) {
|
|
56003
|
+
listenAttempts += 1;
|
|
56004
|
+
const next = listenAttempts === MAX_LISTEN_ATTEMPTS ? 0 : lastTriedPort + 1;
|
|
56005
|
+
log2("warn", `port ${lastTriedPort} busy \u2014 ${next === 0 ? "retrying on an ephemeral port" : `retrying on port ${next}`}`);
|
|
56006
|
+
attemptListen(next);
|
|
56007
|
+
return;
|
|
56008
|
+
}
|
|
56009
|
+
const hint = err2.code === "EADDRINUSE" ? ` \u2014 port ${lastTriedPort} is already in use. Stop the other process or use --port <N>.` : err2.code === "EACCES" ? ` \u2014 port ${lastTriedPort} requires privileges. Use a port >= 1024.` : "";
|
|
55735
56010
|
log2("error", `listen failed: ${err2.code ?? ""} ${err2.message}${hint}`);
|
|
55736
56011
|
shuttingDown = true;
|
|
55737
56012
|
server.close();
|
|
@@ -55748,24 +56023,24 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
55748
56023
|
log2("error", `unhandledRejection: ${String(reason)}`);
|
|
55749
56024
|
});
|
|
55750
56025
|
let shuttingDown = false;
|
|
56026
|
+
const finishShutdown = () => {
|
|
56027
|
+
clearProxyInstanceFile(instanceId);
|
|
56028
|
+
unregisterInstance(instanceId);
|
|
56029
|
+
closeLogger();
|
|
56030
|
+
process.exit(0);
|
|
56031
|
+
};
|
|
55751
56032
|
const shutdown = (sig) => {
|
|
55752
56033
|
if (shuttingDown) return;
|
|
55753
56034
|
shuttingDown = true;
|
|
55754
56035
|
log2("info", `${sig} received \u2014 flushing sessions\u2026`);
|
|
55755
56036
|
server.close(() => {
|
|
55756
56037
|
flushConversations();
|
|
55757
|
-
void flushAllSessions().finally(
|
|
55758
|
-
closeLogger();
|
|
55759
|
-
process.exit(0);
|
|
55760
|
-
});
|
|
56038
|
+
void flushAllSessions().finally(finishShutdown);
|
|
55761
56039
|
});
|
|
55762
56040
|
setTimeout(() => {
|
|
55763
56041
|
log2("warn", "shutdown grace window elapsed; forcing exit");
|
|
55764
56042
|
flushConversations();
|
|
55765
|
-
void flushAllSessions().finally(
|
|
55766
|
-
closeLogger();
|
|
55767
|
-
process.exit(0);
|
|
55768
|
-
});
|
|
56043
|
+
void flushAllSessions().finally(finishShutdown);
|
|
55769
56044
|
}, 1e4).unref?.();
|
|
55770
56045
|
};
|
|
55771
56046
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
@@ -55773,6 +56048,13 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
55773
56048
|
if (process.platform === "win32") {
|
|
55774
56049
|
process.on("SIGBREAK", () => shutdown("SIGBREAK"));
|
|
55775
56050
|
}
|
|
56051
|
+
const parentPid = Number.parseInt(process.env.BILI_PARENT_PID ?? "", 10);
|
|
56052
|
+
if (Number.isInteger(parentPid) && parentPid > 0 && parentPid !== process.pid) {
|
|
56053
|
+
const watcher = setInterval(() => {
|
|
56054
|
+
if (!isPidAlive(parentPid)) shutdown(`parent-gone (pid ${parentPid})`);
|
|
56055
|
+
}, 2e3);
|
|
56056
|
+
watcher.unref?.();
|
|
56057
|
+
}
|
|
55776
56058
|
return server;
|
|
55777
56059
|
}
|
|
55778
56060
|
function isTrustedAdminOrigin(origin, host, trustedHosts) {
|
|
@@ -55799,8 +56081,13 @@ function adminTrustedHosts(bindHost, port) {
|
|
|
55799
56081
|
}
|
|
55800
56082
|
return set;
|
|
55801
56083
|
}
|
|
55802
|
-
async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
56084
|
+
async function handle(req, res, opts, core, config, log2, instanceId, instanceStartedAt) {
|
|
55803
56085
|
const isAdminPath = req.url === "/__bili/" || req.url?.startsWith("/__bili/") || req.url === "/__acp/" || req.url?.startsWith("/__acp/");
|
|
56086
|
+
if (isAdminPath && headerValue2(req, BILI_TUNNEL_HEADER) !== void 0) {
|
|
56087
|
+
res.writeHead(403, { "content-type": "application/json" });
|
|
56088
|
+
res.end(JSON.stringify({ error: "management endpoints are not reachable through the bili tunnel" }));
|
|
56089
|
+
return;
|
|
56090
|
+
}
|
|
55804
56091
|
if (isAdminPath && !isLoopbackAddress(req.socket.remoteAddress)) {
|
|
55805
56092
|
res.writeHead(403, { "content-type": "application/json" });
|
|
55806
56093
|
res.end(JSON.stringify({ error: "management endpoints are loopback-only; access denied for " + (req.socket.remoteAddress ?? "unknown") }));
|
|
@@ -55825,7 +56112,7 @@ async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
|
55825
56112
|
}
|
|
55826
56113
|
if (req.method === "GET" && req.url === "/__bili/health") {
|
|
55827
56114
|
res.writeHead(200, { "content-type": "application/json" });
|
|
55828
|
-
res.end(JSON.stringify({ ok: true, upstream: opts.upstream }));
|
|
56115
|
+
res.end(JSON.stringify({ ok: true, upstream: opts.upstream, instanceId, pid: process.pid, startedAt: instanceStartedAt }));
|
|
55829
56116
|
return;
|
|
55830
56117
|
}
|
|
55831
56118
|
if (req.method === "GET" && req.url === "/__bili/") {
|
|
@@ -55946,6 +56233,19 @@ async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
|
55946
56233
|
urlPath = url.split("?", 2)[0];
|
|
55947
56234
|
responsesCompact = urlPath.endsWith("/responses/compact");
|
|
55948
56235
|
route = resolveUpstream(opts, req.url ?? "", req);
|
|
56236
|
+
if (route?.tunnel) {
|
|
56237
|
+
const verdict = await checkTunnelDestination(route.upstream, {
|
|
56238
|
+
selfPort: req.socket.localPort ?? void 0,
|
|
56239
|
+
clientLoopback: isLoopbackAddress(req.socket.remoteAddress),
|
|
56240
|
+
allowlist: tunnelAllowlistFromEnv()
|
|
56241
|
+
});
|
|
56242
|
+
if (!verdict.ok) {
|
|
56243
|
+
log2("warn", `[tunnel] denied ${maskUrlsInText(route.upstream)}: ${verdict.message}`);
|
|
56244
|
+
res.writeHead(403, { "content-type": "application/json" });
|
|
56245
|
+
res.end(JSON.stringify({ error: verdict.message, code: "tunnel_destination_denied", detail: verdict.code }));
|
|
56246
|
+
return;
|
|
56247
|
+
}
|
|
56248
|
+
}
|
|
55949
56249
|
upstreamOrigin = route ? route.upstream : /^https?:\/\//i.test(url) ? new URL(url).origin : opts.upstream;
|
|
55950
56250
|
protocol = route?.explicitProtocol ?? (req.method === "POST" && bodyBuffer.length > 0 ? urlPath.endsWith("/chat/completions") ? "openai" : urlPath.endsWith("/v1/messages") || urlPath.endsWith("/messages") ? "anthropic" : urlPath.endsWith("/responses") || responsesCompact ? "responses" : null : null);
|
|
55951
56251
|
if (protocol !== null && bodyBuffer.length > 0) {
|
|
@@ -55989,14 +56289,14 @@ async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
|
55989
56289
|
try {
|
|
55990
56290
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
55991
56291
|
try {
|
|
55992
|
-
|
|
56292
|
+
fs7.mkdirSync(rawDir, { recursive: true });
|
|
55993
56293
|
} catch {
|
|
55994
56294
|
}
|
|
55995
56295
|
const hdrs = maskHeadersForLog(
|
|
55996
56296
|
Object.fromEntries(Object.entries(req.headers).map(([k2, v2]) => [k2, Array.isArray(v2) ? v2.join(",") : String(v2)]))
|
|
55997
56297
|
);
|
|
55998
56298
|
const hdrText = Object.entries(hdrs).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
55999
|
-
|
|
56299
|
+
fs7.writeFileSync(`${rawDir}/${Date.now()}-INCOMING.txt`, `${req.method} ${maskUrlsInText(req.url ?? "")}
|
|
56000
56300
|
${hdrText}
|
|
56001
56301
|
|
|
56002
56302
|
${bodyBuffer.toString("utf8")}`);
|
|
@@ -56338,7 +56638,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
56338
56638
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
56339
56639
|
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
56340
56640
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
56341
|
-
rebuiltMessages =
|
|
56641
|
+
rebuiltMessages = systemToUser(coreToOpenai(processedMessages));
|
|
56342
56642
|
const sysParts = [];
|
|
56343
56643
|
if (systemText) sysParts.push(systemText);
|
|
56344
56644
|
if (shouldInject) sysParts.push(buildCompressSystemPrompt(prompts));
|
|
@@ -56675,6 +56975,7 @@ function buildForwardTarget(req, opts, route, affinity, hopMarker) {
|
|
|
56675
56975
|
headers[k2] = Array.isArray(v2) ? v2.join(", ") : v2;
|
|
56676
56976
|
}
|
|
56677
56977
|
if (hopMarker !== void 0) headers[BILI_HOP_HEADER] = hopMarker;
|
|
56978
|
+
if (route?.tunnel) headers[BILI_TUNNEL_HEADER] = "1";
|
|
56678
56979
|
headers["host"] = new URL(upstreamUrl).host;
|
|
56679
56980
|
const betaKey = Object.keys(headers).find((h) => h.toLowerCase() === "x-codex-beta-features");
|
|
56680
56981
|
if (betaKey) {
|
|
@@ -56786,16 +57087,16 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
56786
57087
|
if (bodyDumpEnabled() && process.env.ACP_DUMP_REQ !== "0") {
|
|
56787
57088
|
const dumpDir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
|
|
56788
57089
|
try {
|
|
56789
|
-
|
|
57090
|
+
fs7.mkdirSync(dumpDir, { recursive: true });
|
|
56790
57091
|
} catch {
|
|
56791
57092
|
}
|
|
56792
57093
|
const sid = prepared?.session.id ?? "unknown";
|
|
56793
57094
|
const out = `${dumpDir}/req-${Date.now()}-${safeSessionId(sid)}.json`;
|
|
56794
57095
|
try {
|
|
56795
57096
|
const pretty = JSON.stringify(JSON.parse(body), null, 2);
|
|
56796
|
-
|
|
57097
|
+
fs7.writeFileSync(out, pretty);
|
|
56797
57098
|
} catch {
|
|
56798
|
-
|
|
57099
|
+
fs7.writeFileSync(out, body);
|
|
56799
57100
|
}
|
|
56800
57101
|
log2("info", `[debug] forwarded body written to ${out}`);
|
|
56801
57102
|
}
|
|
@@ -56815,7 +57116,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
56815
57116
|
const rawBase = bodyDumpEnabled() ? (() => {
|
|
56816
57117
|
try {
|
|
56817
57118
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
56818
|
-
|
|
57119
|
+
fs7.mkdirSync(rawDir, { recursive: true });
|
|
56819
57120
|
return `${rawDir}/${Date.now()}-${safeSessionId(prepared?.session.id)}`;
|
|
56820
57121
|
} catch {
|
|
56821
57122
|
return "";
|
|
@@ -56826,7 +57127,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
56826
57127
|
const hdrText = Object.entries(maskHeadersForLog(headers)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
56827
57128
|
const bodyText = req.method === "GET" || req.method === "HEAD" ? "" : typeof body === "string" ? body : Buffer.from(body).toString("utf8");
|
|
56828
57129
|
const reqPath = `${rawBase}-REQ.txt`;
|
|
56829
|
-
|
|
57130
|
+
fs7.writeFileSync(reqPath, `${req.method ?? "POST"} ${maskUrlForLog(upstreamUrl)}
|
|
56830
57131
|
${hdrText}
|
|
56831
57132
|
|
|
56832
57133
|
${bodyText}`);
|
|
@@ -56876,7 +57177,7 @@ ${bodyText}`);
|
|
|
56876
57177
|
try {
|
|
56877
57178
|
const hdrText = Object.entries(maskHeadersForLog(respHeaders)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
56878
57179
|
const resPath = `${rawBase}-RES.txt`;
|
|
56879
|
-
|
|
57180
|
+
fs7.writeFileSync(resPath, `${upstream.status}
|
|
56880
57181
|
${hdrText}
|
|
56881
57182
|
`);
|
|
56882
57183
|
log2("info", `[debug] RAW response dump: ${resPath}`);
|
|
@@ -59175,7 +59476,7 @@ var hr = /* @__PURE__ */ Symbol("entry");
|
|
|
59175
59476
|
var cs = /* @__PURE__ */ Symbol("entryOpt");
|
|
59176
59477
|
var ui = /* @__PURE__ */ Symbol("writeEntryClass");
|
|
59177
59478
|
var lr = /* @__PURE__ */ Symbol("write");
|
|
59178
|
-
var
|
|
59479
|
+
var fs8 = /* @__PURE__ */ Symbol("ondrain");
|
|
59179
59480
|
var wt = class extends A {
|
|
59180
59481
|
sync = false;
|
|
59181
59482
|
opt;
|
|
@@ -59209,8 +59510,8 @@ var wt = class extends A {
|
|
|
59209
59510
|
if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
|
|
59210
59511
|
if (t.gzip && (typeof t.gzip != "object" && (t.gzip = {}), this.portable && (t.gzip.portable = true), this.zip = new ze(t.gzip)), t.brotli && (typeof t.brotli != "object" && (t.brotli = {}), this.zip = new We(t.brotli)), t.zstd && (typeof t.zstd != "object" && (t.zstd = {}), this.zip = new Ye(t.zstd)), !this.zip) throw new Error("impossible");
|
|
59211
59512
|
let e = this.zip;
|
|
59212
|
-
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[
|
|
59213
|
-
} else this.on("drain", this[
|
|
59513
|
+
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs8]()), this.on("resume", () => e.resume());
|
|
59514
|
+
} else this.on("drain", this[fs8]);
|
|
59214
59515
|
this.noDirRecurse = !!t.noDirRecurse, this.follow = !!t.follow, this.noMtime = !!t.noMtime, t.mtime && (this.mtime = t.mtime), this.filter = typeof t.filter == "function" ? t.filter : () => true, this[W] = new hi(), this[G] = 0, this.jobs = Number(t.jobs) || 4, this[Ee] = false, this[me] = false;
|
|
59215
59516
|
}
|
|
59216
59517
|
[lr](t) {
|
|
@@ -59323,7 +59624,7 @@ var wt = class extends A {
|
|
|
59323
59624
|
this.emit("error", e);
|
|
59324
59625
|
}
|
|
59325
59626
|
}
|
|
59326
|
-
[
|
|
59627
|
+
[fs8]() {
|
|
59327
59628
|
this[Et] && this[Et].entry && this[Et].entry.resume();
|
|
59328
59629
|
}
|
|
59329
59630
|
[di](t) {
|
|
@@ -60208,12 +60509,12 @@ var To = (s3) => {
|
|
|
60208
60509
|
};
|
|
60209
60510
|
|
|
60210
60511
|
// src/update.ts
|
|
60211
|
-
import
|
|
60512
|
+
import path11 from "path";
|
|
60212
60513
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
60213
60514
|
var REGISTRY_BASE = "https://registry.npmjs.org";
|
|
60214
60515
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
60215
|
-
var THROTTLE_FILE =
|
|
60216
|
-
var LOCK_FILE =
|
|
60516
|
+
var THROTTLE_FILE = path11.join(cacheDir(), ".update-check");
|
|
60517
|
+
var LOCK_FILE = path11.join(cacheDir(), ".update-lock");
|
|
60217
60518
|
var LOCK_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
60218
60519
|
function shouldStealLock(holderAlive, ageMs) {
|
|
60219
60520
|
return !holderAlive || ageMs >= LOCK_MAX_AGE_MS;
|
|
@@ -60248,27 +60549,27 @@ async function readLastCheck() {
|
|
|
60248
60549
|
}
|
|
60249
60550
|
async function writeLastCheck(ts2) {
|
|
60250
60551
|
try {
|
|
60251
|
-
await mkdir2(
|
|
60552
|
+
await mkdir2(path11.dirname(THROTTLE_FILE), { recursive: true });
|
|
60252
60553
|
await writeFile2(THROTTLE_FILE, String(ts2), "utf-8");
|
|
60253
60554
|
} catch {
|
|
60254
60555
|
}
|
|
60255
60556
|
}
|
|
60256
60557
|
async function findInstallDir(packageName) {
|
|
60257
|
-
let dir =
|
|
60558
|
+
let dir = path11.dirname(fileURLToPath3(import.meta.url));
|
|
60258
60559
|
for (; ; ) {
|
|
60259
60560
|
try {
|
|
60260
|
-
const pkg = JSON.parse(await readFile2(
|
|
60561
|
+
const pkg = JSON.parse(await readFile2(path11.join(dir, "package.json"), "utf-8"));
|
|
60261
60562
|
if (pkg.name === packageName) return dir;
|
|
60262
60563
|
} catch {
|
|
60263
60564
|
}
|
|
60264
|
-
const parent =
|
|
60565
|
+
const parent = path11.dirname(dir);
|
|
60265
60566
|
if (parent === dir) return void 0;
|
|
60266
60567
|
dir = parent;
|
|
60267
60568
|
}
|
|
60268
60569
|
}
|
|
60269
60570
|
async function readDiskVersion(installDir) {
|
|
60270
60571
|
try {
|
|
60271
|
-
const pkg = JSON.parse(await readFile2(
|
|
60572
|
+
const pkg = JSON.parse(await readFile2(path11.join(installDir, "package.json"), "utf-8"));
|
|
60272
60573
|
return pkg.version;
|
|
60273
60574
|
} catch {
|
|
60274
60575
|
return void 0;
|
|
@@ -60305,13 +60606,13 @@ async function syntaxCheckEntry(entryAbs) {
|
|
|
60305
60606
|
} catch (e) {
|
|
60306
60607
|
return `entry unreadable: ${String(e)}`;
|
|
60307
60608
|
}
|
|
60308
|
-
const tmpCheck =
|
|
60609
|
+
const tmpCheck = path11.join(cacheDir(), ".update-syntax-check.mjs");
|
|
60309
60610
|
try {
|
|
60310
60611
|
await mkdir2(cacheDir(), { recursive: true });
|
|
60311
60612
|
await writeFile2(tmpCheck, source);
|
|
60312
60613
|
const r = await runNodeCheck(tmpCheck);
|
|
60313
60614
|
if (r.code !== 0) {
|
|
60314
|
-
return `entry does not parse (${
|
|
60615
|
+
return `entry does not parse (${path11.basename(entryAbs)}): ${r.stderr.split("\n").filter(Boolean).slice(0, 3).join(" | ").slice(0, 300)}`;
|
|
60315
60616
|
}
|
|
60316
60617
|
return null;
|
|
60317
60618
|
} finally {
|
|
@@ -60324,7 +60625,7 @@ async function syntaxCheckEntry(entryAbs) {
|
|
|
60324
60625
|
async function verifyEntries(dir, label) {
|
|
60325
60626
|
let pkg;
|
|
60326
60627
|
try {
|
|
60327
|
-
pkg = JSON.parse(await readFile2(
|
|
60628
|
+
pkg = JSON.parse(await readFile2(path11.join(dir, "package.json"), "utf-8"));
|
|
60328
60629
|
} catch (e) {
|
|
60329
60630
|
return `${label}: package.json unreadable: ${String(e)}`;
|
|
60330
60631
|
}
|
|
@@ -60334,11 +60635,11 @@ async function verifyEntries(dir, label) {
|
|
|
60334
60635
|
}
|
|
60335
60636
|
for (const rel2 of entries) {
|
|
60336
60637
|
try {
|
|
60337
|
-
await access(
|
|
60638
|
+
await access(path11.join(dir, rel2));
|
|
60338
60639
|
} catch {
|
|
60339
60640
|
return `${label}: entry missing: ${rel2}`;
|
|
60340
60641
|
}
|
|
60341
|
-
const reason = await syntaxCheckEntry(
|
|
60642
|
+
const reason = await syntaxCheckEntry(path11.join(dir, rel2));
|
|
60342
60643
|
if (reason) return `${label}: ${reason}`;
|
|
60343
60644
|
}
|
|
60344
60645
|
return null;
|
|
@@ -60543,14 +60844,14 @@ async function installViaTarball(version2, tarballUrl, installDir, integrity, sh
|
|
|
60543
60844
|
if (!v2.ok) {
|
|
60544
60845
|
return { ok: false, error: `tarball integrity verification failed: ${v2.error}` };
|
|
60545
60846
|
}
|
|
60546
|
-
const tmpFile =
|
|
60847
|
+
const tmpFile = path11.join(cacheDir(), `.update-${version2}.tgz`);
|
|
60547
60848
|
try {
|
|
60548
60849
|
await mkdir2(cacheDir(), { recursive: true });
|
|
60549
60850
|
await writeFile2(tmpFile, tgzBuffer);
|
|
60550
60851
|
} catch (e) {
|
|
60551
60852
|
return { ok: false, error: `failed to write temp file ${tmpFile}: ${String(e)}` };
|
|
60552
60853
|
}
|
|
60553
|
-
const stagingDir =
|
|
60854
|
+
const stagingDir = path11.join(cacheDir(), `.update-staging-${version2}`);
|
|
60554
60855
|
try {
|
|
60555
60856
|
await rm2(stagingDir, { recursive: true, force: true });
|
|
60556
60857
|
await mkdir2(stagingDir, { recursive: true });
|
|
@@ -60572,7 +60873,7 @@ async function installViaTarball(version2, tarballUrl, installDir, integrity, sh
|
|
|
60572
60873
|
} finally {
|
|
60573
60874
|
await rm2(tmpFile, { force: true });
|
|
60574
60875
|
}
|
|
60575
|
-
const backupDir =
|
|
60876
|
+
const backupDir = path11.join(cacheDir(), `.update-backup-${version2}`);
|
|
60576
60877
|
try {
|
|
60577
60878
|
await rm2(backupDir, { recursive: true, force: true });
|
|
60578
60879
|
await cp(installDir, backupDir, { recursive: true, force: true });
|
|
@@ -60628,14 +60929,14 @@ function startAutoUpdate(opts) {
|
|
|
60628
60929
|
}
|
|
60629
60930
|
|
|
60630
60931
|
// src/mcp.ts
|
|
60631
|
-
import
|
|
60632
|
-
import
|
|
60932
|
+
import fs9 from "fs";
|
|
60933
|
+
import path12 from "path";
|
|
60633
60934
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
60634
60935
|
var VERSION2 = (() => {
|
|
60635
60936
|
try {
|
|
60636
60937
|
const here = fileURLToPath4(import.meta.url);
|
|
60637
|
-
const pkg =
|
|
60638
|
-
return JSON.parse(
|
|
60938
|
+
const pkg = path12.join(path12.dirname(here), "..", "package.json");
|
|
60939
|
+
return JSON.parse(fs9.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
60639
60940
|
} catch {
|
|
60640
60941
|
return "dev";
|
|
60641
60942
|
}
|
|
@@ -60644,11 +60945,8 @@ var DEFAULT_PROXY_ORIGIN = "http://127.0.0.1:8787";
|
|
|
60644
60945
|
function resolveProxyOrigin() {
|
|
60645
60946
|
const fromEnv = process.env.BILI_MCP_PROXY?.trim();
|
|
60646
60947
|
if (fromEnv && fromEnv.length > 0) return fromEnv;
|
|
60647
|
-
|
|
60648
|
-
|
|
60649
|
-
if (/^https?:\/\/\S+$/.test(discovered)) return discovered;
|
|
60650
|
-
} catch {
|
|
60651
|
-
}
|
|
60948
|
+
const discovered = readProxyInstanceFile();
|
|
60949
|
+
if (discovered && /^https?:\/\/\S+$/.test(discovered.origin)) return discovered.origin;
|
|
60652
60950
|
return DEFAULT_PROXY_ORIGIN;
|
|
60653
60951
|
}
|
|
60654
60952
|
var TOOL_TIMEOUT_MS = 6e4;
|
|
@@ -60807,30 +61105,42 @@ if (process.argv[1] && /(?:^|[\\/])mcp\.(?:ts|js)$/.test(process.argv[1])) {
|
|
|
60807
61105
|
}
|
|
60808
61106
|
|
|
60809
61107
|
// src/plugin-install.ts
|
|
60810
|
-
import
|
|
60811
|
-
import
|
|
61108
|
+
import fs10 from "fs";
|
|
61109
|
+
import path13 from "path";
|
|
60812
61110
|
import os4 from "os";
|
|
60813
61111
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
60814
61112
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
61113
|
+
function proxyOriginForInstall() {
|
|
61114
|
+
const fromEnv = process.env.BILI_MCP_PROXY?.trim();
|
|
61115
|
+
if (fromEnv && fromEnv.length > 0) return fromEnv;
|
|
61116
|
+
const inst = readProxyInstanceFile();
|
|
61117
|
+
if (inst === void 0) {
|
|
61118
|
+
throw new Error("no bili proxy origin found \u2014 start bili first (`bili start` or `bili <client>`), then retry, or set BILI_MCP_PROXY explicitly");
|
|
61119
|
+
}
|
|
61120
|
+
if (isProxyInstanceFile(inst) && !isPidAlive(inst.pid)) {
|
|
61121
|
+
throw new Error(`the recorded bili proxy (pid ${inst.pid}, ${inst.origin}) is not running \u2014 start bili and retry so a dead origin is not frozen into the client config`);
|
|
61122
|
+
}
|
|
61123
|
+
return inst.origin;
|
|
61124
|
+
}
|
|
60815
61125
|
var PLUGIN_AGENTS = ["pi", "omp", "claude", "codex", "opencode"];
|
|
60816
61126
|
function selfPackageRoot() {
|
|
60817
61127
|
const here = fileURLToPath5(import.meta.url);
|
|
60818
|
-
return
|
|
61128
|
+
return path13.resolve(path13.dirname(here), "..");
|
|
60819
61129
|
}
|
|
60820
61130
|
function homeFile(rel2, envOverride) {
|
|
60821
61131
|
const raw = (envOverride !== void 0 ? process.env[envOverride] : void 0)?.trim();
|
|
60822
61132
|
const base = raw && raw.length > 0 ? raw : os4.homedir();
|
|
60823
|
-
return
|
|
61133
|
+
return path13.join(base, rel2);
|
|
60824
61134
|
}
|
|
60825
61135
|
function backupOnce(file) {
|
|
60826
|
-
if (
|
|
60827
|
-
|
|
61136
|
+
if (fs10.existsSync(file) && !fs10.existsSync(`${file}.bili-bak`)) {
|
|
61137
|
+
fs10.copyFileSync(file, `${file}.bili-bak`);
|
|
60828
61138
|
}
|
|
60829
61139
|
}
|
|
60830
61140
|
function readJson(file) {
|
|
60831
61141
|
let text;
|
|
60832
61142
|
try {
|
|
60833
|
-
text =
|
|
61143
|
+
text = fs10.readFileSync(file, "utf8");
|
|
60834
61144
|
} catch (err2) {
|
|
60835
61145
|
if (err2.code === "ENOENT") return {};
|
|
60836
61146
|
throw err2;
|
|
@@ -60839,7 +61149,7 @@ function readJson(file) {
|
|
|
60839
61149
|
try {
|
|
60840
61150
|
parsed = JSON.parse(text);
|
|
60841
61151
|
} catch (err2) {
|
|
60842
|
-
throw new Error(`${file}: not valid JSON (${err2 instanceof Error ? err2.message : String(err2)}) \u2014 fix it or restore ${
|
|
61152
|
+
throw new Error(`${file}: not valid JSON (${err2 instanceof Error ? err2.message : String(err2)}) \u2014 fix it or restore ${path13.basename(file)}.bili-bak first; refusing to overwrite`);
|
|
60843
61153
|
}
|
|
60844
61154
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
60845
61155
|
throw new Error(`${file}: expected a JSON object at top level, refusing to overwrite`);
|
|
@@ -60847,18 +61157,18 @@ function readJson(file) {
|
|
|
60847
61157
|
return parsed;
|
|
60848
61158
|
}
|
|
60849
61159
|
function writeJson(file, data) {
|
|
60850
|
-
|
|
61160
|
+
fs10.mkdirSync(path13.dirname(file), { recursive: true });
|
|
60851
61161
|
backupOnce(file);
|
|
60852
|
-
|
|
61162
|
+
fs10.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
60853
61163
|
}
|
|
60854
61164
|
function requireDistFile(file) {
|
|
60855
|
-
if (!
|
|
61165
|
+
if (!fs10.existsSync(file)) {
|
|
60856
61166
|
process.stderr.write(`bili plugin: warning: ${file} does not exist yet (run \`npm run build\` in ${selfPackageRoot()}) \u2014 the entry will be dead until built
|
|
60857
61167
|
`);
|
|
60858
61168
|
}
|
|
60859
61169
|
}
|
|
60860
61170
|
function piSettingsFile() {
|
|
60861
|
-
return
|
|
61171
|
+
return path13.join(resolvePiHome(process.env), "settings.json");
|
|
60862
61172
|
}
|
|
60863
61173
|
function isPiEntry(entry, root) {
|
|
60864
61174
|
return entry === root || /^npm:billion-context(-pi)?(@|$)/.test(entry) || /(^|[/\\])node_modules[/\\]billion-context(-pi)?([\/\\]|$)/.test(entry) || /(^|[/\\])billion-context(-pi)?$/.test(entry);
|
|
@@ -60895,35 +61205,80 @@ function piStatus() {
|
|
|
60895
61205
|
const list = Array.isArray(packages) ? packages.map(String) : [];
|
|
60896
61206
|
return list.some((p2) => p2 === root) ? "installed" : "not installed";
|
|
60897
61207
|
}
|
|
61208
|
+
var OMP_ENTRY_RE = /[\\/]dist[\\/]agent[\\/]omp\.js$/;
|
|
61209
|
+
function ompExtensionItemLines(text) {
|
|
61210
|
+
const lines = text.split("\n");
|
|
61211
|
+
let keyIdx = -1;
|
|
61212
|
+
for (let i = 0; i < lines.length; i++) {
|
|
61213
|
+
if (/^extensions:(\s+(#.*)?)?$/.test(lines[i])) {
|
|
61214
|
+
if (keyIdx !== -1) return [];
|
|
61215
|
+
keyIdx = i;
|
|
61216
|
+
}
|
|
61217
|
+
}
|
|
61218
|
+
if (keyIdx === -1) return [];
|
|
61219
|
+
const items = [];
|
|
61220
|
+
for (let i = keyIdx + 1; i < lines.length; i++) {
|
|
61221
|
+
const t = lines[i].trimStart();
|
|
61222
|
+
if (t === "" || t.startsWith("#")) continue;
|
|
61223
|
+
if (t === "-" || t.startsWith("- ")) items.push(i);
|
|
61224
|
+
else break;
|
|
61225
|
+
}
|
|
61226
|
+
return items;
|
|
61227
|
+
}
|
|
60898
61228
|
function ompConfigFile() {
|
|
60899
61229
|
const raw = process.env.PI_CODING_AGENT_DIR?.trim();
|
|
60900
|
-
if (raw && raw.length > 0)
|
|
60901
|
-
|
|
61230
|
+
if (raw && raw.length > 0) {
|
|
61231
|
+
if (raw.endsWith("-bili") && raw.length > "-bili".length) {
|
|
61232
|
+
const realHome = raw.slice(0, -"-bili".length);
|
|
61233
|
+
process.stderr.write(
|
|
61234
|
+
`bili plugin: PI_CODING_AGENT_DIR points at the bili overlay ${raw} \u2014 operating on the real omp home ${realHome} instead
|
|
61235
|
+
`
|
|
61236
|
+
);
|
|
61237
|
+
return path13.join(realHome, "config.yml");
|
|
61238
|
+
}
|
|
61239
|
+
return path13.join(raw, "config.yml");
|
|
61240
|
+
}
|
|
61241
|
+
return path13.join(os4.homedir(), ".omp", "agent", "config.yml");
|
|
60902
61242
|
}
|
|
60903
61243
|
function ompExtensionPath() {
|
|
60904
|
-
return
|
|
61244
|
+
return path13.join(selfPackageRoot(), "dist", "agent", "omp.js");
|
|
60905
61245
|
}
|
|
60906
61246
|
function ompEntryValue(line) {
|
|
60907
61247
|
return line.replace(/#.*$/, "").trim().replace(/^-\s*/, "").replace(/^["']|["']$/g, "").trim();
|
|
60908
61248
|
}
|
|
61249
|
+
function ompBlockLoaded(text) {
|
|
61250
|
+
const lines = text.split("\n");
|
|
61251
|
+
return ompExtensionItemLines(text).some((i) => {
|
|
61252
|
+
const v2 = ompEntryValue(lines[i]);
|
|
61253
|
+
return OMP_ENTRY_RE.test(v2) && fs10.existsSync(v2);
|
|
61254
|
+
});
|
|
61255
|
+
}
|
|
60909
61256
|
function ompRemove() {
|
|
60910
61257
|
const file = ompConfigFile();
|
|
60911
|
-
|
|
60912
|
-
|
|
60913
|
-
const
|
|
60914
|
-
const
|
|
60915
|
-
|
|
61258
|
+
if (!fs10.existsSync(file)) return `omp: not installed (${file})`;
|
|
61259
|
+
const text = fs10.readFileSync(file, "utf8");
|
|
61260
|
+
const lines = text.split("\n");
|
|
61261
|
+
const drop = new Set(
|
|
61262
|
+
ompExtensionItemLines(text).filter((i) => OMP_ENTRY_RE.test(ompEntryValue(lines[i])))
|
|
61263
|
+
);
|
|
61264
|
+
if (drop.size === 0) return `omp: not installed (${file})`;
|
|
61265
|
+
const cleaned = lines.filter((_2, i) => !drop.has(i)).join("\n");
|
|
60916
61266
|
backupOnce(file);
|
|
60917
|
-
|
|
61267
|
+
fs10.writeFileSync(file, cleaned);
|
|
60918
61268
|
return `omp: removed from ${file}`;
|
|
60919
61269
|
}
|
|
60920
61270
|
function ompInstall() {
|
|
60921
61271
|
const file = ompConfigFile();
|
|
60922
61272
|
const entry = ompExtensionPath();
|
|
60923
61273
|
requireDistFile(entry);
|
|
60924
|
-
|
|
60925
|
-
|
|
60926
|
-
if (text
|
|
61274
|
+
fs10.mkdirSync(path13.dirname(file), { recursive: true });
|
|
61275
|
+
let text = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
61276
|
+
if (ompBlockLoaded(text)) return `omp: already installed (${file})`;
|
|
61277
|
+
{
|
|
61278
|
+
const lines = text.split("\n");
|
|
61279
|
+
const stale = new Set(ompExtensionItemLines(text).filter((i) => ompEntryValue(lines[i]) === entry));
|
|
61280
|
+
if (stale.size > 0) text = lines.filter((_2, i) => !stale.has(i)).join("\n");
|
|
61281
|
+
}
|
|
60927
61282
|
const keyCount = (text.match(/^extensions:/gm) ?? []).length;
|
|
60928
61283
|
if (keyCount > 1) throw new Error(`${file}: multiple \`extensions:\` keys \u2014 fix the file first, refusing to edit`);
|
|
60929
61284
|
if (/^extensions:\s*\S/m.test(text) && !/^extensions:\s*$/m.test(text)) {
|
|
@@ -60953,26 +61308,31 @@ ${tail}`;
|
|
|
60953
61308
|
- ${entry}
|
|
60954
61309
|
`;
|
|
60955
61310
|
}
|
|
60956
|
-
const
|
|
61311
|
+
const outLines = out.split("\n");
|
|
61312
|
+
const occurrences = ompExtensionItemLines(out).filter((i) => ompEntryValue(outLines[i]) === entry).length;
|
|
60957
61313
|
if (occurrences !== 1) {
|
|
60958
61314
|
throw new Error(`${file}: edit would leave ${occurrences} copies of the entry \u2014 aborting without writing`);
|
|
60959
61315
|
}
|
|
60960
61316
|
backupOnce(file);
|
|
60961
|
-
|
|
61317
|
+
fs10.writeFileSync(file, out);
|
|
60962
61318
|
return `omp: installed -> ${file} extensions += ${entry}`;
|
|
60963
61319
|
}
|
|
60964
61320
|
function ompStatus() {
|
|
60965
61321
|
const file = ompConfigFile();
|
|
60966
|
-
const text =
|
|
60967
|
-
|
|
61322
|
+
const text = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
61323
|
+
const lines = text.split("\n");
|
|
61324
|
+
let broken = false;
|
|
61325
|
+
for (const i of ompExtensionItemLines(text)) {
|
|
61326
|
+
const v2 = ompEntryValue(lines[i]);
|
|
61327
|
+
if (!OMP_ENTRY_RE.test(v2)) continue;
|
|
61328
|
+
if (fs10.existsSync(v2)) return "installed";
|
|
61329
|
+
broken = true;
|
|
61330
|
+
}
|
|
61331
|
+
return broken ? "broken" : "not installed";
|
|
60968
61332
|
}
|
|
60969
61333
|
function ompPluginLoadedFrom(ompHome) {
|
|
60970
61334
|
try {
|
|
60971
|
-
|
|
60972
|
-
return text.split("\n").some((line) => {
|
|
60973
|
-
const v2 = ompEntryValue(line);
|
|
60974
|
-
return /[\\/]dist[\\/]agent[\\/]omp\.js$/.test(v2) && fs9.existsSync(v2);
|
|
60975
|
-
});
|
|
61335
|
+
return ompBlockLoaded(fs10.readFileSync(path13.join(ompHome, "config.yml"), "utf8"));
|
|
60976
61336
|
} catch {
|
|
60977
61337
|
return false;
|
|
60978
61338
|
}
|
|
@@ -60983,11 +61343,11 @@ function claudeMcpJson() {
|
|
|
60983
61343
|
}
|
|
60984
61344
|
function claudeInstall() {
|
|
60985
61345
|
const root = selfPackageRoot();
|
|
60986
|
-
const mcpJs =
|
|
61346
|
+
const mcpJs = path13.join(root, "dist", "mcp.js");
|
|
60987
61347
|
requireDistFile(mcpJs);
|
|
60988
61348
|
const claude = process.env.CLAUDE?.trim() || "claude";
|
|
60989
61349
|
try {
|
|
60990
|
-
execFileSync2(claude, ["mcp", "add", "bili", "--scope", "user", "-e", `BILI_MCP_PROXY=${
|
|
61350
|
+
execFileSync2(claude, ["mcp", "add", "bili", "--scope", "user", "-e", `BILI_MCP_PROXY=${proxyOriginForInstall()}`, "--", process.execPath, mcpJs], { stdio: ["ignore", "pipe", "pipe"], timeout: CLAUDE_EXEC_TIMEOUT_MS });
|
|
60991
61351
|
return `claude: installed via \`claude mcp add\` (user scope) -> ${claudeMcpJson()}`;
|
|
60992
61352
|
} catch (err2) {
|
|
60993
61353
|
const stderr = err2 instanceof Error && "stderr" in err2 ? String(err2.stderr ?? "") : "";
|
|
@@ -61010,38 +61370,38 @@ function claudeStatus() {
|
|
|
61010
61370
|
}
|
|
61011
61371
|
function codexToml() {
|
|
61012
61372
|
const raw = process.env.CODEX_HOME?.trim();
|
|
61013
|
-
if (raw && raw.length > 0) return
|
|
61373
|
+
if (raw && raw.length > 0) return path13.join(raw, "config.toml");
|
|
61014
61374
|
return homeFile(".codex/config.toml");
|
|
61015
61375
|
}
|
|
61016
61376
|
function codexBlock() {
|
|
61017
61377
|
return `
|
|
61018
61378
|
[mcp_servers.bili]
|
|
61019
61379
|
command = ${JSON.stringify(process.execPath)}
|
|
61020
|
-
args = [${JSON.stringify(
|
|
61021
|
-
env = { BILI_MCP_PROXY = ${JSON.stringify(
|
|
61380
|
+
args = [${JSON.stringify(path13.join(selfPackageRoot(), "dist", "mcp.js"))}]
|
|
61381
|
+
env = { BILI_MCP_PROXY = ${JSON.stringify(proxyOriginForInstall())} }
|
|
61022
61382
|
`;
|
|
61023
61383
|
}
|
|
61024
61384
|
function codexInstall() {
|
|
61025
61385
|
const file = codexToml();
|
|
61026
|
-
const text =
|
|
61386
|
+
const text = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
61027
61387
|
const existing = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
|
|
61028
61388
|
if (existing !== null) {
|
|
61029
61389
|
const block = text.slice(existing.index, text.indexOf("\n[", existing.index + 1) === -1 ? void 0 : text.indexOf("\n[", existing.index + 1));
|
|
61030
|
-
if (block.includes(`BILI_MCP_PROXY = ${JSON.stringify(
|
|
61390
|
+
if (block.includes(`BILI_MCP_PROXY = ${JSON.stringify(proxyOriginForInstall())}`)) return `codex: already installed (${file})`;
|
|
61031
61391
|
const refreshed = text.slice(0, existing.index) + codexBlock().replace(/^\n/, "") + text.slice(existing.index + block.length);
|
|
61032
61392
|
backupOnce(file);
|
|
61033
|
-
|
|
61393
|
+
fs10.writeFileSync(file, refreshed);
|
|
61034
61394
|
return `codex: refreshed proxy origin -> ${file} [mcp_servers.bili]`;
|
|
61035
61395
|
}
|
|
61036
|
-
|
|
61396
|
+
fs10.mkdirSync(path13.dirname(file), { recursive: true });
|
|
61037
61397
|
backupOnce(file);
|
|
61038
|
-
|
|
61398
|
+
fs10.writeFileSync(file, text + (text.endsWith("\n") || text.length === 0 ? "" : "\n") + codexBlock());
|
|
61039
61399
|
return `codex: installed -> ${file} [mcp_servers.bili]`;
|
|
61040
61400
|
}
|
|
61041
61401
|
function codexRemove() {
|
|
61042
61402
|
const file = codexToml();
|
|
61043
|
-
if (!
|
|
61044
|
-
const text =
|
|
61403
|
+
if (!fs10.existsSync(file)) return `codex: not installed (${file})`;
|
|
61404
|
+
const text = fs10.readFileSync(file, "utf8");
|
|
61045
61405
|
const start = (() => {
|
|
61046
61406
|
const m2 = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
|
|
61047
61407
|
return m2 === null ? -1 : m2.index;
|
|
@@ -61054,28 +61414,28 @@ function codexRemove() {
|
|
|
61054
61414
|
const end = nextTable >= 0 ? start + firstNewline + 1 + nextTable : text.length;
|
|
61055
61415
|
const cleaned = (text.slice(0, lineStart).replace(/\n+$/, "\n") + text.slice(end)).replace(/^\n+/, "");
|
|
61056
61416
|
backupOnce(file);
|
|
61057
|
-
|
|
61417
|
+
fs10.writeFileSync(file, cleaned);
|
|
61058
61418
|
return `codex: removed from ${file}`;
|
|
61059
61419
|
}
|
|
61060
61420
|
function codexStatus() {
|
|
61061
|
-
const text =
|
|
61421
|
+
const text = fs10.existsSync(codexToml()) ? fs10.readFileSync(codexToml(), "utf8") : "";
|
|
61062
61422
|
return /^\[mcp_servers\.bili\]\s*$/m.test(text) ? "installed" : "not installed";
|
|
61063
61423
|
}
|
|
61064
61424
|
function opencodeJson() {
|
|
61065
61425
|
const raw = process.env.OPENCODE_CONFIG?.trim();
|
|
61066
61426
|
if (raw && raw.length > 0) return raw;
|
|
61067
61427
|
const xdg2 = process.env.XDG_CONFIG_HOME?.trim();
|
|
61068
|
-
if (xdg2 && xdg2.length > 0) return
|
|
61069
|
-
return
|
|
61428
|
+
if (xdg2 && xdg2.length > 0) return path13.join(xdg2, "opencode/opencode.json");
|
|
61429
|
+
return path13.join(os4.homedir(), ".config", "opencode", "opencode.json");
|
|
61070
61430
|
}
|
|
61071
61431
|
function opencodeInstall() {
|
|
61072
61432
|
const file = opencodeJson();
|
|
61073
|
-
const mcpJs =
|
|
61433
|
+
const mcpJs = path13.join(selfPackageRoot(), "dist", "mcp.js");
|
|
61074
61434
|
requireDistFile(mcpJs);
|
|
61075
61435
|
const data = readJson(file);
|
|
61076
61436
|
const mcp = data.mcp ?? {};
|
|
61077
61437
|
if ("bili" in mcp) return `opencode: already installed (${file})`;
|
|
61078
|
-
mcp.bili = { type: "local", command: [process.execPath, mcpJs], environment: { BILI_MCP_PROXY:
|
|
61438
|
+
mcp.bili = { type: "local", command: [process.execPath, mcpJs], environment: { BILI_MCP_PROXY: proxyOriginForInstall() }, enabled: true };
|
|
61079
61439
|
data.mcp = mcp;
|
|
61080
61440
|
writeJson(file, data);
|
|
61081
61441
|
return `opencode: installed -> ${file} mcp.bili`;
|
|
@@ -61121,15 +61481,15 @@ function pluginStatusAll() {
|
|
|
61121
61481
|
}
|
|
61122
61482
|
|
|
61123
61483
|
// src/launcher.ts
|
|
61124
|
-
import { randomUUID as
|
|
61125
|
-
import
|
|
61484
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
61485
|
+
import fs11 from "fs";
|
|
61126
61486
|
import net2 from "net";
|
|
61127
61487
|
import os5 from "os";
|
|
61128
|
-
import
|
|
61488
|
+
import path14 from "path";
|
|
61129
61489
|
import { pathToFileURL } from "url";
|
|
61130
61490
|
import { spawn } from "child_process";
|
|
61131
61491
|
function selfDistFile(name) {
|
|
61132
|
-
return
|
|
61492
|
+
return path14.join(selfPackageRoot(), "dist", name);
|
|
61133
61493
|
}
|
|
61134
61494
|
var LAUNCHER_DEFAULT_HOST = "127.0.0.1";
|
|
61135
61495
|
var LAUNCHER_DEFAULT_PORT = 8787;
|
|
@@ -61165,12 +61525,12 @@ function unwrapUpstream2(url) {
|
|
|
61165
61525
|
return idx >= 0 ? url.slice(idx + "/bili/".length) : url;
|
|
61166
61526
|
}
|
|
61167
61527
|
function resolveCaCertPath(env) {
|
|
61168
|
-
const base = env.XDG_DATA_HOME ||
|
|
61169
|
-
return
|
|
61528
|
+
const base = env.XDG_DATA_HOME || path14.join(os5.homedir(), ".local/share");
|
|
61529
|
+
return path14.join(base, "billion-context", "ca", "root-ca.pem");
|
|
61170
61530
|
}
|
|
61171
61531
|
function resolveCombinedCaPath(env) {
|
|
61172
|
-
const base = env.XDG_DATA_HOME ||
|
|
61173
|
-
return
|
|
61532
|
+
const base = env.XDG_DATA_HOME || path14.join(os5.homedir(), ".local/share");
|
|
61533
|
+
return path14.join(base, "billion-context", "ca", "combined-ca.pem");
|
|
61174
61534
|
}
|
|
61175
61535
|
function discoverRoutes(client, config) {
|
|
61176
61536
|
const httpsDomains = [];
|
|
@@ -61403,12 +61763,12 @@ function buildCodexMcpArgs(origin, conversationId2) {
|
|
|
61403
61763
|
];
|
|
61404
61764
|
}
|
|
61405
61765
|
function overlayLockPath(overlay) {
|
|
61406
|
-
return
|
|
61766
|
+
return path14.join(overlay, ".bili-launch.pid");
|
|
61407
61767
|
}
|
|
61408
61768
|
function livePidHoldsOverlay(overlay) {
|
|
61409
61769
|
let raw;
|
|
61410
61770
|
try {
|
|
61411
|
-
raw =
|
|
61771
|
+
raw = fs11.readFileSync(overlayLockPath(overlay), "utf8");
|
|
61412
61772
|
} catch {
|
|
61413
61773
|
return void 0;
|
|
61414
61774
|
}
|
|
@@ -61422,10 +61782,10 @@ function livePidHoldsOverlay(overlay) {
|
|
|
61422
61782
|
return pid;
|
|
61423
61783
|
}
|
|
61424
61784
|
function linkOverlayEntry(realHome, overlay, entry) {
|
|
61425
|
-
const target =
|
|
61426
|
-
const link =
|
|
61785
|
+
const target = path14.join(realHome, entry);
|
|
61786
|
+
const link = path14.join(overlay, entry);
|
|
61427
61787
|
try {
|
|
61428
|
-
|
|
61788
|
+
fs11.symlinkSync(target, link);
|
|
61429
61789
|
return true;
|
|
61430
61790
|
} catch (err2) {
|
|
61431
61791
|
const code = err2.code;
|
|
@@ -61433,24 +61793,24 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
61433
61793
|
}
|
|
61434
61794
|
let st2;
|
|
61435
61795
|
try {
|
|
61436
|
-
st2 =
|
|
61796
|
+
st2 = fs11.lstatSync(target);
|
|
61437
61797
|
} catch {
|
|
61438
61798
|
return false;
|
|
61439
61799
|
}
|
|
61440
61800
|
if (st2.isDirectory()) {
|
|
61441
61801
|
try {
|
|
61442
|
-
|
|
61802
|
+
fs11.symlinkSync(target, link, "junction");
|
|
61443
61803
|
return true;
|
|
61444
61804
|
} catch {
|
|
61445
61805
|
return false;
|
|
61446
61806
|
}
|
|
61447
61807
|
}
|
|
61448
61808
|
try {
|
|
61449
|
-
|
|
61809
|
+
fs11.linkSync(target, link);
|
|
61450
61810
|
return true;
|
|
61451
61811
|
} catch {
|
|
61452
61812
|
try {
|
|
61453
|
-
|
|
61813
|
+
fs11.copyFileSync(target, link);
|
|
61454
61814
|
return true;
|
|
61455
61815
|
} catch {
|
|
61456
61816
|
return false;
|
|
@@ -61460,7 +61820,7 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
61460
61820
|
function isWriteThroughHardlink(overlayPath, realPath, st2) {
|
|
61461
61821
|
if (st2.isDirectory() || st2.isSymbolicLink() || st2.nlink <= 1) return false;
|
|
61462
61822
|
try {
|
|
61463
|
-
const realSt =
|
|
61823
|
+
const realSt = fs11.lstatSync(realPath);
|
|
61464
61824
|
return st2.dev === realSt.dev && st2.ino === realSt.ino;
|
|
61465
61825
|
} catch {
|
|
61466
61826
|
return false;
|
|
@@ -61472,7 +61832,7 @@ function sqliteSetMembers(base) {
|
|
|
61472
61832
|
function mergeSqliteSet(overlay, realHome, base) {
|
|
61473
61833
|
const members = sqliteSetMembers(base).filter((m2) => {
|
|
61474
61834
|
try {
|
|
61475
|
-
return
|
|
61835
|
+
return fs11.lstatSync(path14.join(overlay, m2)).isFile();
|
|
61476
61836
|
} catch {
|
|
61477
61837
|
return false;
|
|
61478
61838
|
}
|
|
@@ -61490,44 +61850,44 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
61490
61850
|
};
|
|
61491
61851
|
try {
|
|
61492
61852
|
for (const m2 of members) {
|
|
61493
|
-
const src =
|
|
61494
|
-
const dst =
|
|
61853
|
+
const src = path14.join(overlay, m2);
|
|
61854
|
+
const dst = path14.join(realHome, m2);
|
|
61495
61855
|
let dstStat;
|
|
61496
61856
|
try {
|
|
61497
|
-
dstStat =
|
|
61857
|
+
dstStat = fs11.lstatSync(dst);
|
|
61498
61858
|
} catch {
|
|
61499
61859
|
}
|
|
61500
61860
|
if (dstStat && dstStat.isDirectory()) {
|
|
61501
61861
|
rollback();
|
|
61502
61862
|
return false;
|
|
61503
61863
|
}
|
|
61504
|
-
const srcStat =
|
|
61864
|
+
const srcStat = fs11.lstatSync(src);
|
|
61505
61865
|
if (dstStat && dstStat.mtimeMs >= srcStat.mtimeMs) {
|
|
61506
61866
|
try {
|
|
61507
|
-
|
|
61867
|
+
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
61508
61868
|
} catch {
|
|
61509
61869
|
rollback();
|
|
61510
61870
|
return false;
|
|
61511
61871
|
}
|
|
61512
|
-
undo.push(() =>
|
|
61872
|
+
undo.push(() => fs11.renameSync(`${dst}.bili-conflict`, src));
|
|
61513
61873
|
continue;
|
|
61514
61874
|
}
|
|
61515
61875
|
if (dstStat) {
|
|
61516
61876
|
try {
|
|
61517
|
-
|
|
61877
|
+
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
61518
61878
|
} catch {
|
|
61519
61879
|
rollback();
|
|
61520
61880
|
return false;
|
|
61521
61881
|
}
|
|
61522
|
-
undo.push(() =>
|
|
61882
|
+
undo.push(() => fs11.renameSync(`${dst}.bili-conflict`, dst));
|
|
61523
61883
|
}
|
|
61524
61884
|
try {
|
|
61525
|
-
|
|
61885
|
+
fs11.renameSync(src, dst);
|
|
61526
61886
|
} catch {
|
|
61527
61887
|
rollback();
|
|
61528
61888
|
return false;
|
|
61529
61889
|
}
|
|
61530
|
-
undo.push(() =>
|
|
61890
|
+
undo.push(() => fs11.renameSync(dst, src));
|
|
61531
61891
|
}
|
|
61532
61892
|
return true;
|
|
61533
61893
|
} catch {
|
|
@@ -61537,7 +61897,7 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
61537
61897
|
}
|
|
61538
61898
|
function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
61539
61899
|
try {
|
|
61540
|
-
|
|
61900
|
+
fs11.mkdirSync(overlay, { recursive: true });
|
|
61541
61901
|
} catch {
|
|
61542
61902
|
return false;
|
|
61543
61903
|
}
|
|
@@ -61548,19 +61908,19 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61548
61908
|
);
|
|
61549
61909
|
}
|
|
61550
61910
|
try {
|
|
61551
|
-
|
|
61911
|
+
fs11.writeFileSync(overlayLockPath(overlay), `${process.pid}
|
|
61552
61912
|
`);
|
|
61553
61913
|
} catch {
|
|
61554
61914
|
}
|
|
61555
61915
|
const realEntries = /* @__PURE__ */ new Set();
|
|
61556
61916
|
try {
|
|
61557
|
-
for (const entry of
|
|
61917
|
+
for (const entry of fs11.readdirSync(realHome)) realEntries.add(entry);
|
|
61558
61918
|
} catch {
|
|
61559
61919
|
}
|
|
61560
61920
|
try {
|
|
61561
61921
|
let overlayEntries;
|
|
61562
61922
|
try {
|
|
61563
|
-
overlayEntries =
|
|
61923
|
+
overlayEntries = fs11.readdirSync(overlay);
|
|
61564
61924
|
} catch {
|
|
61565
61925
|
overlayEntries = [];
|
|
61566
61926
|
}
|
|
@@ -61571,10 +61931,10 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61571
61931
|
if (!members.some((m2) => m2 !== entry && overlayEntries.includes(m2))) continue;
|
|
61572
61932
|
let mainSt;
|
|
61573
61933
|
try {
|
|
61574
|
-
mainSt =
|
|
61934
|
+
mainSt = fs11.lstatSync(path14.join(overlay, entry));
|
|
61575
61935
|
} catch {
|
|
61576
61936
|
}
|
|
61577
|
-
const keepSidecars = mainSt !== void 0 && isWriteThroughHardlink(
|
|
61937
|
+
const keepSidecars = mainSt !== void 0 && isWriteThroughHardlink(path14.join(overlay, entry), path14.join(realHome, entry), mainSt);
|
|
61578
61938
|
dbSets.push({ base: entry, keepSidecars });
|
|
61579
61939
|
}
|
|
61580
61940
|
const skipEntries = /* @__PURE__ */ new Set();
|
|
@@ -61585,10 +61945,10 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61585
61945
|
}
|
|
61586
61946
|
for (const entry of overlayEntries) {
|
|
61587
61947
|
if (entry === generatedFile) continue;
|
|
61588
|
-
const overlayPath =
|
|
61948
|
+
const overlayPath = path14.join(overlay, entry);
|
|
61589
61949
|
if (entry.startsWith(`.${generatedFile}.`) && entry.endsWith(".tmp")) {
|
|
61590
61950
|
try {
|
|
61591
|
-
|
|
61951
|
+
fs11.unlinkSync(overlayPath);
|
|
61592
61952
|
} catch {
|
|
61593
61953
|
}
|
|
61594
61954
|
continue;
|
|
@@ -61596,33 +61956,33 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61596
61956
|
if (skipEntries.has(entry)) continue;
|
|
61597
61957
|
let st2;
|
|
61598
61958
|
try {
|
|
61599
|
-
st2 =
|
|
61959
|
+
st2 = fs11.lstatSync(overlayPath);
|
|
61600
61960
|
} catch {
|
|
61601
61961
|
continue;
|
|
61602
61962
|
}
|
|
61603
61963
|
if (st2.isSymbolicLink()) {
|
|
61604
61964
|
let target;
|
|
61605
61965
|
try {
|
|
61606
|
-
target =
|
|
61966
|
+
target = fs11.readlinkSync(overlayPath);
|
|
61607
61967
|
} catch {
|
|
61608
61968
|
}
|
|
61609
|
-
const wanted = realEntries.has(entry) ?
|
|
61969
|
+
const wanted = realEntries.has(entry) ? path14.join(realHome, entry) : void 0;
|
|
61610
61970
|
if (!wanted || target !== wanted) {
|
|
61611
61971
|
try {
|
|
61612
|
-
|
|
61972
|
+
fs11.unlinkSync(overlayPath);
|
|
61613
61973
|
} catch {
|
|
61614
61974
|
}
|
|
61615
61975
|
}
|
|
61616
61976
|
} else if (realEntries.has(entry)) {
|
|
61617
|
-
const realPath =
|
|
61977
|
+
const realPath = path14.join(realHome, entry);
|
|
61618
61978
|
if (isWriteThroughHardlink(overlayPath, realPath, st2)) {
|
|
61619
61979
|
try {
|
|
61620
|
-
|
|
61980
|
+
fs11.unlinkSync(overlayPath);
|
|
61621
61981
|
} catch {
|
|
61622
61982
|
}
|
|
61623
|
-
} else if (mergeOverlayEntry(overlayPath, realPath)) {
|
|
61983
|
+
} else if (mergeOverlayEntry(overlayPath, realPath, generatedFile)) {
|
|
61624
61984
|
try {
|
|
61625
|
-
|
|
61985
|
+
fs11.rmSync(overlayPath, { recursive: true, force: true });
|
|
61626
61986
|
} catch {
|
|
61627
61987
|
}
|
|
61628
61988
|
} else {
|
|
@@ -61644,10 +62004,10 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61644
62004
|
for (const entry of realEntries) {
|
|
61645
62005
|
if (entry === generatedFile) continue;
|
|
61646
62006
|
total += 1;
|
|
61647
|
-
const overlayPath =
|
|
62007
|
+
const overlayPath = path14.join(overlay, entry);
|
|
61648
62008
|
let present = false;
|
|
61649
62009
|
try {
|
|
61650
|
-
|
|
62010
|
+
fs11.lstatSync(overlayPath);
|
|
61651
62011
|
present = true;
|
|
61652
62012
|
} catch {
|
|
61653
62013
|
}
|
|
@@ -61676,47 +62036,48 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61676
62036
|
}
|
|
61677
62037
|
return true;
|
|
61678
62038
|
}
|
|
61679
|
-
function mergeOverlayEntry(src, dst) {
|
|
62039
|
+
function mergeOverlayEntry(src, dst, excludedName) {
|
|
61680
62040
|
let st2;
|
|
61681
62041
|
try {
|
|
61682
|
-
st2 =
|
|
62042
|
+
st2 = fs11.lstatSync(src);
|
|
61683
62043
|
} catch {
|
|
61684
62044
|
return true;
|
|
61685
62045
|
}
|
|
61686
62046
|
let dstStat;
|
|
61687
62047
|
try {
|
|
61688
|
-
dstStat =
|
|
62048
|
+
dstStat = fs11.lstatSync(dst);
|
|
61689
62049
|
} catch {
|
|
61690
62050
|
}
|
|
61691
62051
|
if (st2.isDirectory()) {
|
|
61692
62052
|
if (dstStat && !dstStat.isDirectory()) {
|
|
61693
62053
|
try {
|
|
61694
|
-
|
|
62054
|
+
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
61695
62055
|
dstStat = void 0;
|
|
61696
62056
|
} catch {
|
|
61697
62057
|
return false;
|
|
61698
62058
|
}
|
|
61699
62059
|
}
|
|
61700
62060
|
try {
|
|
61701
|
-
|
|
62061
|
+
fs11.mkdirSync(dst, { recursive: true });
|
|
61702
62062
|
} catch {
|
|
61703
62063
|
return false;
|
|
61704
62064
|
}
|
|
61705
62065
|
let entries;
|
|
61706
62066
|
try {
|
|
61707
|
-
entries =
|
|
62067
|
+
entries = fs11.readdirSync(src);
|
|
61708
62068
|
} catch {
|
|
61709
62069
|
return false;
|
|
61710
62070
|
}
|
|
61711
62071
|
let ok = true;
|
|
61712
62072
|
for (const entry of entries) {
|
|
61713
|
-
if (
|
|
62073
|
+
if (excludedName !== void 0 && entry === excludedName) continue;
|
|
62074
|
+
if (!mergeOverlayEntry(path14.join(src, entry), path14.join(dst, entry), excludedName)) ok = false;
|
|
61714
62075
|
}
|
|
61715
62076
|
return ok;
|
|
61716
62077
|
}
|
|
61717
62078
|
if (dstStat && dstStat.isDirectory()) {
|
|
61718
62079
|
try {
|
|
61719
|
-
|
|
62080
|
+
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
61720
62081
|
return true;
|
|
61721
62082
|
} catch {
|
|
61722
62083
|
return false;
|
|
@@ -61725,13 +62086,13 @@ function mergeOverlayEntry(src, dst) {
|
|
|
61725
62086
|
if (st2.isSymbolicLink()) {
|
|
61726
62087
|
if (dstStat) {
|
|
61727
62088
|
try {
|
|
61728
|
-
|
|
62089
|
+
fs11.unlinkSync(src);
|
|
61729
62090
|
} catch {
|
|
61730
62091
|
}
|
|
61731
62092
|
return true;
|
|
61732
62093
|
}
|
|
61733
62094
|
try {
|
|
61734
|
-
|
|
62095
|
+
fs11.renameSync(src, dst);
|
|
61735
62096
|
} catch {
|
|
61736
62097
|
return false;
|
|
61737
62098
|
}
|
|
@@ -61739,7 +62100,7 @@ function mergeOverlayEntry(src, dst) {
|
|
|
61739
62100
|
}
|
|
61740
62101
|
if (dstStat && dstStat.mtimeMs >= st2.mtimeMs) {
|
|
61741
62102
|
try {
|
|
61742
|
-
|
|
62103
|
+
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
61743
62104
|
return true;
|
|
61744
62105
|
} catch {
|
|
61745
62106
|
return false;
|
|
@@ -61747,13 +62108,13 @@ function mergeOverlayEntry(src, dst) {
|
|
|
61747
62108
|
}
|
|
61748
62109
|
if (dstStat) {
|
|
61749
62110
|
try {
|
|
61750
|
-
|
|
62111
|
+
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
61751
62112
|
} catch {
|
|
61752
62113
|
return false;
|
|
61753
62114
|
}
|
|
61754
62115
|
}
|
|
61755
62116
|
try {
|
|
61756
|
-
|
|
62117
|
+
fs11.renameSync(src, dst);
|
|
61757
62118
|
return true;
|
|
61758
62119
|
} catch {
|
|
61759
62120
|
return false;
|
|
@@ -61763,7 +62124,7 @@ function piPluginInstalled(piHome) {
|
|
|
61763
62124
|
const root = selfPackageRoot();
|
|
61764
62125
|
if (!root) return false;
|
|
61765
62126
|
try {
|
|
61766
|
-
const parsed = JSON.parse(
|
|
62127
|
+
const parsed = JSON.parse(fs11.readFileSync(path14.join(piHome, "settings.json"), "utf8"));
|
|
61767
62128
|
const list = Array.isArray(parsed.packages) ? parsed.packages.map(String) : [];
|
|
61768
62129
|
return list.some((p2) => isBiliPiEntry(p2, root));
|
|
61769
62130
|
} catch {
|
|
@@ -61771,23 +62132,23 @@ function piPluginInstalled(piHome) {
|
|
|
61771
62132
|
}
|
|
61772
62133
|
}
|
|
61773
62134
|
function writeOverlayFileAtomic(overlay, fileName, contents) {
|
|
61774
|
-
const draft =
|
|
62135
|
+
const draft = path14.join(overlay, `.${fileName}.${process.pid}.tmp`);
|
|
61775
62136
|
try {
|
|
61776
|
-
|
|
61777
|
-
|
|
62137
|
+
fs11.writeFileSync(draft, contents);
|
|
62138
|
+
fs11.renameSync(draft, path14.join(overlay, fileName));
|
|
61778
62139
|
} catch {
|
|
61779
62140
|
try {
|
|
61780
|
-
|
|
62141
|
+
fs11.rmSync(draft, { force: true });
|
|
61781
62142
|
} catch {
|
|
61782
62143
|
}
|
|
61783
62144
|
}
|
|
61784
62145
|
}
|
|
61785
62146
|
function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
61786
62147
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
|
|
61787
|
-
const modelsPath =
|
|
62148
|
+
const modelsPath = path14.join(piHome, "models.json");
|
|
61788
62149
|
let txt;
|
|
61789
62150
|
try {
|
|
61790
|
-
txt =
|
|
62151
|
+
txt = fs11.readFileSync(modelsPath, "utf8");
|
|
61791
62152
|
} catch {
|
|
61792
62153
|
return void 0;
|
|
61793
62154
|
}
|
|
@@ -61823,12 +62184,64 @@ function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
|
61823
62184
|
writeOverlayFileAtomic(overlay, "models.json", JSON.stringify(root));
|
|
61824
62185
|
return overlay;
|
|
61825
62186
|
}
|
|
62187
|
+
function atomicWriteTextFile(filePath, contents) {
|
|
62188
|
+
const draft = `${filePath}.${process.pid}.bili-tmp`;
|
|
62189
|
+
try {
|
|
62190
|
+
fs11.writeFileSync(draft, contents);
|
|
62191
|
+
fs11.renameSync(draft, filePath);
|
|
62192
|
+
} catch {
|
|
62193
|
+
try {
|
|
62194
|
+
fs11.rmSync(draft, { force: true });
|
|
62195
|
+
} catch {
|
|
62196
|
+
}
|
|
62197
|
+
throw new Error(`bili: could not write ${filePath}`);
|
|
62198
|
+
}
|
|
62199
|
+
}
|
|
62200
|
+
function liveProxyPorts() {
|
|
62201
|
+
const ports = /* @__PURE__ */ new Set();
|
|
62202
|
+
const inst = readProxyInstanceFile();
|
|
62203
|
+
if (isProxyInstanceFile(inst)) {
|
|
62204
|
+
if (isPidAlive(inst.pid)) ports.add(inst.port);
|
|
62205
|
+
} else if (inst) {
|
|
62206
|
+
try {
|
|
62207
|
+
ports.add(new URL(inst.origin).port === "" ? 80 : Number(new URL(inst.origin).port));
|
|
62208
|
+
} catch {
|
|
62209
|
+
}
|
|
62210
|
+
}
|
|
62211
|
+
return ports;
|
|
62212
|
+
}
|
|
62213
|
+
function unpackDeadProxyUrlsInFile(filePath, livePorts) {
|
|
62214
|
+
let txt;
|
|
62215
|
+
try {
|
|
62216
|
+
txt = fs11.readFileSync(filePath, "utf8");
|
|
62217
|
+
} catch {
|
|
62218
|
+
return 0;
|
|
62219
|
+
}
|
|
62220
|
+
const re2 = /https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):(\d+)\/bili\/(https?:\/\/\S+)/g;
|
|
62221
|
+
let changed = 0;
|
|
62222
|
+
const out = txt.replace(re2, (full, portStr, raw) => {
|
|
62223
|
+
if (livePorts.has(Number(portStr))) return full;
|
|
62224
|
+
changed += 1;
|
|
62225
|
+
return raw;
|
|
62226
|
+
});
|
|
62227
|
+
if (changed === 0) return 0;
|
|
62228
|
+
try {
|
|
62229
|
+
atomicWriteTextFile(filePath, out);
|
|
62230
|
+
} catch {
|
|
62231
|
+
return 0;
|
|
62232
|
+
}
|
|
62233
|
+
return changed;
|
|
62234
|
+
}
|
|
61826
62235
|
function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
|
|
62236
|
+
const modelsPath = path14.join(ompHome, "models.yml");
|
|
62237
|
+
const unpacked = unpackDeadProxyUrlsInFile(modelsPath, liveProxyPorts());
|
|
62238
|
+
if (unpacked > 0) {
|
|
62239
|
+
console.error(`bili: unpacked ${unpacked} dead proxy URL(s) from the real ${modelsPath}`);
|
|
62240
|
+
}
|
|
61827
62241
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
|
|
61828
|
-
const modelsPath = path13.join(ompHome, "models.yml");
|
|
61829
62242
|
let txt;
|
|
61830
62243
|
try {
|
|
61831
|
-
txt =
|
|
62244
|
+
txt = fs11.readFileSync(modelsPath, "utf8");
|
|
61832
62245
|
} catch {
|
|
61833
62246
|
return void 0;
|
|
61834
62247
|
}
|
|
@@ -61872,10 +62285,10 @@ function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
|
|
|
61872
62285
|
}
|
|
61873
62286
|
function prepareHermesHome(hermesHome, origin, rewrites) {
|
|
61874
62287
|
if (rewrites.length === 0) return void 0;
|
|
61875
|
-
const cfgPath =
|
|
62288
|
+
const cfgPath = path14.join(hermesHome, "config.yaml");
|
|
61876
62289
|
let txt;
|
|
61877
62290
|
try {
|
|
61878
|
-
txt =
|
|
62291
|
+
txt = fs11.readFileSync(cfgPath, "utf8");
|
|
61879
62292
|
} catch {
|
|
61880
62293
|
return void 0;
|
|
61881
62294
|
}
|
|
@@ -61902,21 +62315,21 @@ function prepareHermesHome(hermesHome, origin, rewrites) {
|
|
|
61902
62315
|
}
|
|
61903
62316
|
function writeHermesIdentityPlugin(hermesHome, overlay, rewrites) {
|
|
61904
62317
|
try {
|
|
61905
|
-
if (
|
|
62318
|
+
if (fs11.existsSync(path14.join(hermesHome, "plugins"))) return false;
|
|
61906
62319
|
} catch {
|
|
61907
62320
|
return false;
|
|
61908
62321
|
}
|
|
61909
|
-
const dir =
|
|
62322
|
+
const dir = path14.join("plugins", "model-providers", "bili-session-identity");
|
|
61910
62323
|
try {
|
|
61911
|
-
|
|
62324
|
+
fs11.mkdirSync(path14.join(overlay, dir), { recursive: true });
|
|
61912
62325
|
} catch {
|
|
61913
62326
|
return false;
|
|
61914
62327
|
}
|
|
61915
62328
|
const keys = rewrites.map((r) => r.key);
|
|
61916
|
-
const pluginDir =
|
|
62329
|
+
const pluginDir = path14.join(overlay, dir);
|
|
61917
62330
|
try {
|
|
61918
|
-
|
|
61919
|
-
|
|
62331
|
+
fs11.writeFileSync(path14.join(pluginDir, "__init__.py"), hermesIdentityPluginSource(keys));
|
|
62332
|
+
fs11.writeFileSync(path14.join(pluginDir, "plugin.yaml"), [
|
|
61920
62333
|
"name: bili-session-identity",
|
|
61921
62334
|
"kind: model-provider",
|
|
61922
62335
|
"version: 1.0.0",
|
|
@@ -61928,7 +62341,7 @@ function writeHermesIdentityPlugin(hermesHome, overlay, rewrites) {
|
|
|
61928
62341
|
return false;
|
|
61929
62342
|
}
|
|
61930
62343
|
try {
|
|
61931
|
-
return
|
|
62344
|
+
return fs11.existsSync(path14.join(overlay, dir, "__init__.py"));
|
|
61932
62345
|
} catch {
|
|
61933
62346
|
return false;
|
|
61934
62347
|
}
|
|
@@ -61985,10 +62398,10 @@ function hermesIdentityPluginSource(providerKeys) {
|
|
|
61985
62398
|
].join("\n");
|
|
61986
62399
|
}
|
|
61987
62400
|
function prepareDshHome(dshHome, origin, rewrites) {
|
|
61988
|
-
const cfgPath =
|
|
62401
|
+
const cfgPath = path14.join(dshHome, "settings.yaml");
|
|
61989
62402
|
let txt;
|
|
61990
62403
|
try {
|
|
61991
|
-
txt =
|
|
62404
|
+
txt = fs11.readFileSync(cfgPath, "utf8");
|
|
61992
62405
|
} catch {
|
|
61993
62406
|
return void 0;
|
|
61994
62407
|
}
|
|
@@ -62016,16 +62429,16 @@ function writeDshAcpPatch(dshHome) {
|
|
|
62016
62429
|
const pluginUrl = pathToFileURL(selfDistFile("agent/dsh-acp.js")).href;
|
|
62017
62430
|
const dir = `${dshHome}-bili`;
|
|
62018
62431
|
try {
|
|
62019
|
-
|
|
62432
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
62020
62433
|
} catch {
|
|
62021
62434
|
return void 0;
|
|
62022
62435
|
}
|
|
62023
62436
|
writeOverlayFileAtomic(dir, ".bili-acp.patch.yml", `- insert:
|
|
62024
62437
|
- name: ${pluginUrl}
|
|
62025
62438
|
`);
|
|
62026
|
-
const file =
|
|
62439
|
+
const file = path14.join(dir, ".bili-acp.patch.yml");
|
|
62027
62440
|
try {
|
|
62028
|
-
return
|
|
62441
|
+
return fs11.existsSync(file) ? file : void 0;
|
|
62029
62442
|
} catch {
|
|
62030
62443
|
return void 0;
|
|
62031
62444
|
}
|
|
@@ -62040,7 +62453,7 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
|
|
|
62040
62453
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0 && !pluginPath) return void 0;
|
|
62041
62454
|
let root = {};
|
|
62042
62455
|
try {
|
|
62043
|
-
const txt =
|
|
62456
|
+
const txt = fs11.readFileSync(configFile2, "utf8");
|
|
62044
62457
|
const parsed = JSON.parse(txt);
|
|
62045
62458
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
62046
62459
|
root = { ...parsed };
|
|
@@ -62068,9 +62481,9 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
|
|
|
62068
62481
|
if (!plugins.includes(pluginPath)) plugins.push(pluginPath);
|
|
62069
62482
|
root.plugin = plugins;
|
|
62070
62483
|
}
|
|
62071
|
-
const tmp =
|
|
62072
|
-
const tmpFile =
|
|
62073
|
-
|
|
62484
|
+
const tmp = fs11.mkdtempSync(path14.join(os5.tmpdir(), "bili-opencode-"));
|
|
62485
|
+
const tmpFile = path14.join(tmp, "opencode.json");
|
|
62486
|
+
fs11.writeFileSync(tmpFile, JSON.stringify(root));
|
|
62074
62487
|
return tmpFile;
|
|
62075
62488
|
}
|
|
62076
62489
|
function dedupeInOrder(list) {
|
|
@@ -62104,27 +62517,33 @@ async function probeHealth(origin, fetchImpl) {
|
|
|
62104
62517
|
return false;
|
|
62105
62518
|
}
|
|
62106
62519
|
}
|
|
62107
|
-
function
|
|
62108
|
-
|
|
62109
|
-
const
|
|
62110
|
-
|
|
62111
|
-
|
|
62112
|
-
|
|
62113
|
-
}
|
|
62114
|
-
|
|
62115
|
-
|
|
62116
|
-
|
|
62117
|
-
|
|
62118
|
-
|
|
62119
|
-
|
|
62120
|
-
|
|
62121
|
-
|
|
62122
|
-
|
|
62123
|
-
|
|
62124
|
-
|
|
62125
|
-
|
|
62126
|
-
|
|
62127
|
-
|
|
62520
|
+
async function fetchHealthInfoDefault(origin) {
|
|
62521
|
+
try {
|
|
62522
|
+
const res = await fetch(healthUrl(origin), { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
|
|
62523
|
+
if (!res.ok) return void 0;
|
|
62524
|
+
const data = await res.json();
|
|
62525
|
+
return { ok: Boolean(data.ok), instanceId: typeof data.instanceId === "string" ? data.instanceId : void 0 };
|
|
62526
|
+
} catch {
|
|
62527
|
+
return void 0;
|
|
62528
|
+
}
|
|
62529
|
+
}
|
|
62530
|
+
function instanceCompatible(inst, opts) {
|
|
62531
|
+
if (inst.host !== opts.host || inst.passthrough !== opts.passthrough) return false;
|
|
62532
|
+
const wantDomains = opts.mitmDomains ?? [];
|
|
62533
|
+
if (inst.mitmDomains.length !== wantDomains.length || inst.mitmDomains.some((d, i) => d !== wantDomains[i])) return false;
|
|
62534
|
+
const wantWindows = opts.modelWindows ?? {};
|
|
62535
|
+
const keys = Object.keys(wantWindows);
|
|
62536
|
+
if (Object.keys(inst.modelWindows).length !== keys.length) return false;
|
|
62537
|
+
return keys.every((k2) => inst.modelWindows[k2] === wantWindows[k2]);
|
|
62538
|
+
}
|
|
62539
|
+
async function probeExistingInstance(readInstance, fetchHealthInfo) {
|
|
62540
|
+
const inst = readInstance();
|
|
62541
|
+
if (!isProxyInstanceFile(inst)) return void 0;
|
|
62542
|
+
if (!isPidAlive(inst.pid)) return void 0;
|
|
62543
|
+
const health = await fetchHealthInfo(inst.origin);
|
|
62544
|
+
if (!health || !health.ok) return void 0;
|
|
62545
|
+
if (health.instanceId !== void 0 && health.instanceId !== inst.instanceId) return void 0;
|
|
62546
|
+
return inst;
|
|
62128
62547
|
}
|
|
62129
62548
|
var INHERITED_PROXY_VARS = ["http_proxy", "https_proxy", "all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY"];
|
|
62130
62549
|
function stripInheritedProxy(env) {
|
|
@@ -62140,25 +62559,34 @@ function proxyStartArgs(opts) {
|
|
|
62140
62559
|
}
|
|
62141
62560
|
async function ensureProxyRunning(opts, deps = {}) {
|
|
62142
62561
|
const fetchImpl = deps.fetchImpl ?? defaultFetch;
|
|
62562
|
+
const fetchHealthInfo = deps.fetchHealthInfo ?? fetchHealthInfoDefault;
|
|
62563
|
+
const readInstance = deps.readInstanceFile ?? readProxyInstanceFile;
|
|
62143
62564
|
const spawnImpl = deps.spawnImpl ?? spawn;
|
|
62144
62565
|
const now = deps.now ?? Date.now;
|
|
62145
62566
|
const sleepImpl = deps.sleep ?? ((ms2) => new Promise((r) => setTimeout(r, ms2)));
|
|
62146
|
-
const
|
|
62147
|
-
|
|
62567
|
+
const existing = await probeExistingInstance(readInstance, fetchHealthInfo);
|
|
62568
|
+
if (existing && instanceCompatible(existing, opts)) {
|
|
62569
|
+
console.error(`bili: attaching to running proxy at ${existing.origin} (pid ${existing.pid})`);
|
|
62570
|
+
return { origin: existing.origin, port: existing.port, attached: true };
|
|
62571
|
+
}
|
|
62572
|
+
const launchToken = randomUUID5();
|
|
62573
|
+
const port = opts.port;
|
|
62148
62574
|
const script = process.argv[1];
|
|
62149
62575
|
if (!script) throw new Error("bili: cannot resolve launcher script path");
|
|
62150
|
-
const logPath2 =
|
|
62151
|
-
const logFd =
|
|
62576
|
+
const logPath2 = path14.join(os5.tmpdir(), `bili-proxy-${port}.log`);
|
|
62577
|
+
const logFd = fs11.openSync(logPath2, "a");
|
|
62152
62578
|
let child;
|
|
62153
62579
|
try {
|
|
62154
62580
|
child = spawnImpl(
|
|
62155
62581
|
process.execPath,
|
|
62156
|
-
[script, ...proxyStartArgs(
|
|
62582
|
+
[script, ...proxyStartArgs(opts)],
|
|
62157
62583
|
{
|
|
62158
62584
|
detached: true,
|
|
62159
62585
|
stdio: ["ignore", logFd, logFd],
|
|
62160
62586
|
env: {
|
|
62161
62587
|
...stripInheritedProxy(process.env),
|
|
62588
|
+
BILI_LAUNCH_TOKEN: launchToken,
|
|
62589
|
+
BILI_PARENT_PID: String(process.pid),
|
|
62162
62590
|
...opts.mitmDomains && opts.mitmDomains.length ? { BILI_MITM_DOMAINS: opts.mitmDomains.join(",") } : {},
|
|
62163
62591
|
...opts.modelWindows && Object.keys(opts.modelWindows).length > 0 ? { BILI_LAUNCHER_MODEL_WINDOWS: JSON.stringify(opts.modelWindows) } : {}
|
|
62164
62592
|
}
|
|
@@ -62166,7 +62594,7 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
62166
62594
|
);
|
|
62167
62595
|
} finally {
|
|
62168
62596
|
try {
|
|
62169
|
-
|
|
62597
|
+
fs11.closeSync(logFd);
|
|
62170
62598
|
} catch {
|
|
62171
62599
|
}
|
|
62172
62600
|
}
|
|
@@ -62177,16 +62605,28 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
62177
62605
|
const deadline = now() + SPAWN_WAIT_MS;
|
|
62178
62606
|
while (now() < deadline) {
|
|
62179
62607
|
await sleepImpl(HEALTH_POLL_INTERVAL_MS);
|
|
62180
|
-
|
|
62181
|
-
|
|
62608
|
+
const inst = readInstance();
|
|
62609
|
+
if (isProxyInstanceFile(inst) && inst.launchToken === launchToken) {
|
|
62610
|
+
if (await probeHealth(inst.origin, fetchImpl)) {
|
|
62611
|
+
return { origin: inst.origin, port: inst.port, child, logPath: logPath2 };
|
|
62612
|
+
}
|
|
62613
|
+
continue;
|
|
62614
|
+
}
|
|
62615
|
+
const stale = !isProxyInstanceFile(inst) || !isPidAlive(inst.pid);
|
|
62616
|
+
if (stale && await probeHealth(proxyOrigin(opts.host, port), fetchImpl)) {
|
|
62617
|
+
return { origin: proxyOrigin(opts.host, port), port, child, logPath: logPath2 };
|
|
62182
62618
|
}
|
|
62183
62619
|
}
|
|
62184
|
-
throw new Error(`bili: proxy did not become healthy
|
|
62620
|
+
throw new Error(`bili: proxy did not become healthy within ${SPAWN_WAIT_MS}ms (log: ${logPath2})`);
|
|
62185
62621
|
}
|
|
62186
62622
|
function stopProxy(handle2) {
|
|
62623
|
+
if (handle2.attached) return;
|
|
62187
62624
|
const child = handle2.child;
|
|
62188
62625
|
if (!child || child.pid === void 0) return;
|
|
62189
|
-
if (process.platform
|
|
62626
|
+
if (process.platform === "win32") {
|
|
62627
|
+
return;
|
|
62628
|
+
}
|
|
62629
|
+
if (child.pid > 0) {
|
|
62190
62630
|
try {
|
|
62191
62631
|
process.kill(-child.pid);
|
|
62192
62632
|
} catch {
|
|
@@ -62213,12 +62653,12 @@ var PATH_EXTS = process.platform === "win32" ? [".cmd", ".bat", ".exe", ""] : ["
|
|
|
62213
62653
|
function resolveOnPath(name, env) {
|
|
62214
62654
|
const p2 = env.PATH;
|
|
62215
62655
|
if (!p2) return void 0;
|
|
62216
|
-
for (const dir of p2.split(
|
|
62656
|
+
for (const dir of p2.split(path14.delimiter)) {
|
|
62217
62657
|
if (!dir) continue;
|
|
62218
62658
|
for (const ext of PATH_EXTS) {
|
|
62219
|
-
const f2 =
|
|
62659
|
+
const f2 = path14.join(dir, name + ext);
|
|
62220
62660
|
try {
|
|
62221
|
-
if (
|
|
62661
|
+
if (fs11.existsSync(f2) && fs11.statSync(f2).isFile()) return f2;
|
|
62222
62662
|
} catch {
|
|
62223
62663
|
}
|
|
62224
62664
|
}
|
|
@@ -62236,7 +62676,7 @@ function resolveClientCommand(client, env) {
|
|
|
62236
62676
|
if (piBin) return { command: piBin, prefixArgs: [] };
|
|
62237
62677
|
const piResolved = resolveOnPath("pi", env);
|
|
62238
62678
|
if (piResolved) return { command: piResolved, prefixArgs: [] };
|
|
62239
|
-
const cli =
|
|
62679
|
+
const cli = path14.join(
|
|
62240
62680
|
os5.homedir(),
|
|
62241
62681
|
".pi/agent/npm/node_modules/@earendil-works/pi-coding-agent/dist/cli.js"
|
|
62242
62682
|
);
|
|
@@ -62308,7 +62748,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
62308
62748
|
piOverlayHome = preparePiHttpRewrite(resolvePiHome(process.env), origin, routes.httpRewrites, routes.httpsRewrites);
|
|
62309
62749
|
if (piOverlayHome) env.PI_CODING_AGENT_DIR = piOverlayHome;
|
|
62310
62750
|
const piExt = selfDistFile("agent/pi.js");
|
|
62311
|
-
if (piExt &&
|
|
62751
|
+
if (piExt && fs11.existsSync(piExt) && !piPluginInstalled(resolvePiHome(process.env))) {
|
|
62312
62752
|
clientArgs = ["-e", piExt, ...clientArgs];
|
|
62313
62753
|
}
|
|
62314
62754
|
} else if (base === "omp") {
|
|
@@ -62316,13 +62756,13 @@ async function runLaunch(params, deps = {}) {
|
|
|
62316
62756
|
ompOverlayHome = prepareOmpHttpRewrite(resolveOmpHome(process.env), origin, routes.httpRewrites, routes.httpsRewrites);
|
|
62317
62757
|
if (ompOverlayHome) env.PI_CODING_AGENT_DIR = ompOverlayHome;
|
|
62318
62758
|
const ompExt = selfDistFile("agent/omp.js");
|
|
62319
|
-
if (ompExt &&
|
|
62759
|
+
if (ompExt && fs11.existsSync(ompExt) && !ompPluginLoadedFrom(resolveOmpHome(process.env))) {
|
|
62320
62760
|
clientArgs = ["-e", ompExt, ...clientArgs];
|
|
62321
62761
|
}
|
|
62322
62762
|
} else if (base === "opencode") {
|
|
62323
62763
|
env = { ...process.env, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: ca, BILLION_CONTEXT_PROXY: origin };
|
|
62324
62764
|
const opencodePlugin = selfDistFile("agent/opencode.js");
|
|
62325
|
-
const opencodePluginPath = opencodePlugin &&
|
|
62765
|
+
const opencodePluginPath = opencodePlugin && fs11.existsSync(opencodePlugin) ? opencodePlugin : void 0;
|
|
62326
62766
|
opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
|
|
62327
62767
|
if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
|
|
62328
62768
|
} else if (base === "hermes") {
|
|
@@ -62360,7 +62800,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
62360
62800
|
const dshAcpPatch = writeDshAcpPatch(dshHomeDir);
|
|
62361
62801
|
if (dshAcpPatch) clientArgs = dshArgsWithPatch(clientArgs, dshAcpPatch);
|
|
62362
62802
|
} else if (base === "codex") {
|
|
62363
|
-
const codexConversationId = injectMcp ?
|
|
62803
|
+
const codexConversationId = injectMcp ? randomUUID5() : void 0;
|
|
62364
62804
|
if (directUrl) {
|
|
62365
62805
|
env = { ...process.env, BILLION_CONTEXT_PROXY: origin };
|
|
62366
62806
|
if (codexConversationId) clientArgs = [...buildCodexMcpArgs(origin, codexConversationId), ...clientArgs];
|
|
@@ -62395,8 +62835,8 @@ async function runLaunch(params, deps = {}) {
|
|
|
62395
62835
|
console.error(`bili: claude budget aligned \u2014 CLAUDE_CODE_AUTO_COMPACT_WINDOW=${claudeBudget.CLAUDE_CODE_AUTO_COMPACT_WINDOW}`);
|
|
62396
62836
|
}
|
|
62397
62837
|
if (injectMcp) {
|
|
62398
|
-
const mcpFile =
|
|
62399
|
-
|
|
62838
|
+
const mcpFile = path14.join(os5.tmpdir(), `bili-mcp-${Date.now()}.json`);
|
|
62839
|
+
fs11.writeFileSync(mcpFile, JSON.stringify(buildMcpConfig(origin)));
|
|
62400
62840
|
tmpFiles.push(mcpFile);
|
|
62401
62841
|
clientArgs = ["--mcp-config", mcpFile, ...clientArgs];
|
|
62402
62842
|
}
|
|
@@ -62415,13 +62855,13 @@ async function runLaunch(params, deps = {}) {
|
|
|
62415
62855
|
stopProxy(handle2);
|
|
62416
62856
|
if (opencodeTmpFile) {
|
|
62417
62857
|
try {
|
|
62418
|
-
|
|
62858
|
+
fs11.rmSync(path14.dirname(opencodeTmpFile), { recursive: true, force: true });
|
|
62419
62859
|
} catch {
|
|
62420
62860
|
}
|
|
62421
62861
|
}
|
|
62422
62862
|
for (const f2 of tmpFiles) {
|
|
62423
62863
|
try {
|
|
62424
|
-
|
|
62864
|
+
fs11.rmSync(f2, { force: true });
|
|
62425
62865
|
} catch {
|
|
62426
62866
|
}
|
|
62427
62867
|
}
|
|
@@ -62447,8 +62887,8 @@ async function runTestPi(params, deps = {}) {
|
|
|
62447
62887
|
}
|
|
62448
62888
|
const ca = resolveCaCertPath(process.env);
|
|
62449
62889
|
const env = buildPiEnv(handle2.origin, ca, process.env);
|
|
62450
|
-
const sessionDir =
|
|
62451
|
-
|
|
62890
|
+
const sessionDir = path14.join(os5.tmpdir(), `bili-pi-test-${Date.now()}`);
|
|
62891
|
+
fs11.mkdirSync(sessionDir, { recursive: true });
|
|
62452
62892
|
const args = [
|
|
62453
62893
|
"-p",
|
|
62454
62894
|
"--no-session",
|
|
@@ -62476,7 +62916,7 @@ async function runTestPi(params, deps = {}) {
|
|
|
62476
62916
|
|
|
62477
62917
|
// src/export.ts
|
|
62478
62918
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
62479
|
-
import
|
|
62919
|
+
import path15 from "path";
|
|
62480
62920
|
function fmtDate(ms2) {
|
|
62481
62921
|
return ms2 ? new Date(ms2).toISOString().replace("T", " ").slice(0, 19) + " UTC" : "\u2014";
|
|
62482
62922
|
}
|
|
@@ -62608,7 +63048,7 @@ async function exportSession(selector, opts = {}) {
|
|
|
62608
63048
|
}
|
|
62609
63049
|
const markdown = renderHandoff(matches[0], opts.full ?? false);
|
|
62610
63050
|
if (opts.output) {
|
|
62611
|
-
mkdirSync5(
|
|
63051
|
+
mkdirSync5(path15.dirname(path15.resolve(opts.output)), { recursive: true });
|
|
62612
63052
|
writeFileSync4(opts.output, markdown, "utf8");
|
|
62613
63053
|
return `written to ${opts.output}`;
|
|
62614
63054
|
}
|
|
@@ -62618,11 +63058,11 @@ async function exportSession(selector, opts = {}) {
|
|
|
62618
63058
|
// src/cli.ts
|
|
62619
63059
|
import { readFileSync as readFileSync4 } from "fs";
|
|
62620
63060
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
62621
|
-
import
|
|
63061
|
+
import path16 from "path";
|
|
62622
63062
|
var VERSION3 = (() => {
|
|
62623
63063
|
try {
|
|
62624
63064
|
const here = fileURLToPath6(import.meta.url);
|
|
62625
|
-
const pkg =
|
|
63065
|
+
const pkg = path16.join(path16.dirname(here), "..", "package.json");
|
|
62626
63066
|
return JSON.parse(readFileSync4(pkg, "utf8")).version ?? "dev";
|
|
62627
63067
|
} catch {
|
|
62628
63068
|
return "dev";
|
|
@@ -62631,7 +63071,7 @@ var VERSION3 = (() => {
|
|
|
62631
63071
|
var PACKAGE_NAME = (() => {
|
|
62632
63072
|
try {
|
|
62633
63073
|
const here = fileURLToPath6(import.meta.url);
|
|
62634
|
-
const pkg =
|
|
63074
|
+
const pkg = path16.join(path16.dirname(here), "..", "package.json");
|
|
62635
63075
|
return JSON.parse(readFileSync4(pkg, "utf8")).name ?? "billion-context";
|
|
62636
63076
|
} catch {
|
|
62637
63077
|
return "billion-context";
|