billion-context 0.1.67 → 0.1.68-pr.360.258
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 +70 -0
- package/dist/agent/omp.js +9 -1
- package/dist/agent/omp.js.map +1 -1
- package/dist/agent/pi.js +9 -1
- package/dist/agent/pi.js.map +1 -1
- package/dist/index.js +914 -403
- 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
|
},
|
|
@@ -53022,6 +53142,65 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
|
|
|
53022
53142
|
return current;
|
|
53023
53143
|
}
|
|
53024
53144
|
|
|
53145
|
+
// src/acp-panel.ts
|
|
53146
|
+
var PANEL_BOX_TOP = "\u256D";
|
|
53147
|
+
var PANEL_BOX_TITLE = "ACP Context Analysis";
|
|
53148
|
+
var PANEL_FALLBACK_HEADER = "\u{1F4CA} ACP status";
|
|
53149
|
+
function isAcpPanelText(text) {
|
|
53150
|
+
const t = text.trim();
|
|
53151
|
+
if (t.length === 0) return false;
|
|
53152
|
+
if (t.startsWith(PANEL_BOX_TOP) && t.includes(PANEL_BOX_TITLE)) return true;
|
|
53153
|
+
if (t.startsWith(PANEL_FALLBACK_HEADER)) return true;
|
|
53154
|
+
return false;
|
|
53155
|
+
}
|
|
53156
|
+
function messageText(content) {
|
|
53157
|
+
if (typeof content === "string") return content;
|
|
53158
|
+
if (Array.isArray(content)) {
|
|
53159
|
+
let joined = "";
|
|
53160
|
+
for (const part of content) {
|
|
53161
|
+
const p2 = part;
|
|
53162
|
+
if (p2 === null || typeof p2 !== "object") return void 0;
|
|
53163
|
+
const pt2 = p2.type;
|
|
53164
|
+
if (pt2 !== void 0 && pt2 !== "text" && pt2 !== "input_text" && pt2 !== "output_text") return void 0;
|
|
53165
|
+
if (typeof p2.text === "string") joined += p2.text;
|
|
53166
|
+
}
|
|
53167
|
+
return joined;
|
|
53168
|
+
}
|
|
53169
|
+
return void 0;
|
|
53170
|
+
}
|
|
53171
|
+
function stripAcpPanelMessages(messages) {
|
|
53172
|
+
if (!Array.isArray(messages)) return 0;
|
|
53173
|
+
let stripped = 0;
|
|
53174
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
53175
|
+
const rec = messages[i];
|
|
53176
|
+
if (rec === null || typeof rec !== "object") continue;
|
|
53177
|
+
if (rec.role !== "user") continue;
|
|
53178
|
+
const text = messageText(rec.content);
|
|
53179
|
+
if (text !== void 0 && isAcpPanelText(text)) {
|
|
53180
|
+
messages.splice(i, 1);
|
|
53181
|
+
stripped++;
|
|
53182
|
+
}
|
|
53183
|
+
}
|
|
53184
|
+
return stripped;
|
|
53185
|
+
}
|
|
53186
|
+
function stripAcpPanelResponsesInput(input) {
|
|
53187
|
+
if (!Array.isArray(input)) return 0;
|
|
53188
|
+
let stripped = 0;
|
|
53189
|
+
for (let i = input.length - 1; i >= 0; i--) {
|
|
53190
|
+
const rec = input[i];
|
|
53191
|
+
if (rec === null || typeof rec !== "object") continue;
|
|
53192
|
+
const type = rec.type;
|
|
53193
|
+
if (type !== "message" && type !== void 0) continue;
|
|
53194
|
+
if (rec.role !== "user") continue;
|
|
53195
|
+
const text = messageText(rec.content);
|
|
53196
|
+
if (text !== void 0 && isAcpPanelText(text)) {
|
|
53197
|
+
input.splice(i, 1);
|
|
53198
|
+
stripped++;
|
|
53199
|
+
}
|
|
53200
|
+
}
|
|
53201
|
+
return stripped;
|
|
53202
|
+
}
|
|
53203
|
+
|
|
53025
53204
|
// src/stream-openai.ts
|
|
53026
53205
|
function rewriteOpenaiJsonResponse(body, ctx) {
|
|
53027
53206
|
if (!body || typeof body !== "object") return body;
|
|
@@ -53630,13 +53809,13 @@ function buildStatusPanel(input) {
|
|
|
53630
53809
|
|
|
53631
53810
|
// src/plugin.ts
|
|
53632
53811
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
53633
|
-
import
|
|
53634
|
-
import
|
|
53812
|
+
import fs4 from "fs";
|
|
53813
|
+
import path8 from "path";
|
|
53635
53814
|
var PROXY_VERSION = (() => {
|
|
53636
53815
|
try {
|
|
53637
53816
|
const here = fileURLToPath2(import.meta.url);
|
|
53638
|
-
const pkg =
|
|
53639
|
-
return JSON.parse(
|
|
53817
|
+
const pkg = path8.join(path8.dirname(here), "..", "package.json");
|
|
53818
|
+
return JSON.parse(fs4.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
53640
53819
|
} catch {
|
|
53641
53820
|
return "dev";
|
|
53642
53821
|
}
|
|
@@ -53648,8 +53827,8 @@ var PLUGIN_PROTOCOL_VERSION = 1;
|
|
|
53648
53827
|
var VERSION = (() => {
|
|
53649
53828
|
try {
|
|
53650
53829
|
const here = fileURLToPath2(import.meta.url);
|
|
53651
|
-
const pkg =
|
|
53652
|
-
return JSON.parse(
|
|
53830
|
+
const pkg = path8.join(path8.dirname(here), "..", "package.json");
|
|
53831
|
+
return JSON.parse(fs4.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
53653
53832
|
} catch {
|
|
53654
53833
|
return "dev";
|
|
53655
53834
|
}
|
|
@@ -53678,14 +53857,20 @@ function pluginReportedContextWindow(headers) {
|
|
|
53678
53857
|
var MAX_PLUGIN_CONVERSATIONS = 1024;
|
|
53679
53858
|
var conversations = /* @__PURE__ */ new Map();
|
|
53680
53859
|
var remembered = /* @__PURE__ */ new Map();
|
|
53681
|
-
var conversationsFile = () =>
|
|
53860
|
+
var conversationsFile = () => path8.join(stateDir(), "plugin-conversations.json");
|
|
53682
53861
|
var conversationsSaveTimer;
|
|
53862
|
+
var conversationsDirty = false;
|
|
53683
53863
|
function writeConversationsFile() {
|
|
53864
|
+
if (!conversationsDirty) return;
|
|
53684
53865
|
try {
|
|
53685
53866
|
const obj = {};
|
|
53686
53867
|
for (const [k2, v2] of conversations) obj[k2] = v2;
|
|
53687
|
-
|
|
53688
|
-
|
|
53868
|
+
fs4.mkdirSync(stateDir(), { recursive: true });
|
|
53869
|
+
const filePath = conversationsFile();
|
|
53870
|
+
const draft = `${filePath}.${process.pid}.bili-tmp`;
|
|
53871
|
+
fs4.writeFileSync(draft, JSON.stringify(obj));
|
|
53872
|
+
fs4.renameSync(draft, filePath);
|
|
53873
|
+
conversationsDirty = false;
|
|
53689
53874
|
} catch {
|
|
53690
53875
|
}
|
|
53691
53876
|
}
|
|
@@ -53704,8 +53889,13 @@ function flushConversations() {
|
|
|
53704
53889
|
writeConversationsFile();
|
|
53705
53890
|
}
|
|
53706
53891
|
function loadConversations() {
|
|
53892
|
+
let raw;
|
|
53893
|
+
try {
|
|
53894
|
+
raw = fs4.readFileSync(conversationsFile(), "utf8");
|
|
53895
|
+
} catch {
|
|
53896
|
+
return;
|
|
53897
|
+
}
|
|
53707
53898
|
try {
|
|
53708
|
-
const raw = fs3.readFileSync(conversationsFile(), "utf8");
|
|
53709
53899
|
const obj = JSON.parse(raw);
|
|
53710
53900
|
for (const [k2, v2] of Object.entries(obj)) {
|
|
53711
53901
|
if (v2 && typeof v2.sessionId === "string" && v2.sessionId.length > 0) {
|
|
@@ -53713,11 +53903,18 @@ function loadConversations() {
|
|
|
53713
53903
|
}
|
|
53714
53904
|
}
|
|
53715
53905
|
} catch {
|
|
53906
|
+
try {
|
|
53907
|
+
fs4.renameSync(conversationsFile(), `${conversationsFile()}.corrupt-${Date.now()}`);
|
|
53908
|
+
} catch {
|
|
53909
|
+
}
|
|
53910
|
+
log("warn", "[plugin] plugin-conversations.json is corrupt \u2014 backed up beside the original, starting an empty routing table");
|
|
53716
53911
|
}
|
|
53912
|
+
conversationsDirty = false;
|
|
53717
53913
|
}
|
|
53718
53914
|
function recordPluginSession(conversationId2, sessionId) {
|
|
53719
53915
|
conversations.delete(conversationId2);
|
|
53720
53916
|
conversations.set(conversationId2, { sessionId, lastSeen: Date.now() });
|
|
53917
|
+
conversationsDirty = true;
|
|
53721
53918
|
if (conversations.size > MAX_PLUGIN_CONVERSATIONS) {
|
|
53722
53919
|
const oldest = conversations.keys().next().value;
|
|
53723
53920
|
if (oldest !== void 0) conversations.delete(oldest);
|
|
@@ -54167,14 +54364,14 @@ async function pipePluginJson(stream2, res, session, protocol) {
|
|
|
54167
54364
|
import tls3 from "tls";
|
|
54168
54365
|
|
|
54169
54366
|
// src/discover.ts
|
|
54170
|
-
import
|
|
54367
|
+
import fs6 from "fs";
|
|
54171
54368
|
import os2 from "os";
|
|
54172
|
-
import
|
|
54369
|
+
import path10 from "path";
|
|
54173
54370
|
|
|
54174
54371
|
// src/client-config.ts
|
|
54175
|
-
import
|
|
54372
|
+
import fs5 from "fs";
|
|
54176
54373
|
import os from "os";
|
|
54177
|
-
import
|
|
54374
|
+
import path9 from "path";
|
|
54178
54375
|
function toModelWindow(id, contextWindow) {
|
|
54179
54376
|
return typeof id === "string" && id.length > 0 && typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > 0 ? { id, contextWindow: Math.floor(contextWindow) } : null;
|
|
54180
54377
|
}
|
|
@@ -54183,7 +54380,7 @@ function nonEmpty2(s3) {
|
|
|
54183
54380
|
}
|
|
54184
54381
|
function readJsonObject(filePath) {
|
|
54185
54382
|
try {
|
|
54186
|
-
const txt =
|
|
54383
|
+
const txt = fs5.readFileSync(filePath, "utf8");
|
|
54187
54384
|
const parsed = JSON.parse(txt);
|
|
54188
54385
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
54189
54386
|
} catch {
|
|
@@ -54192,19 +54389,19 @@ function readJsonObject(filePath) {
|
|
|
54192
54389
|
}
|
|
54193
54390
|
function resolvePiHome(env) {
|
|
54194
54391
|
const h = os.homedir();
|
|
54195
|
-
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : nonEmpty2(env.PI_HOME) ? env.PI_HOME :
|
|
54392
|
+
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
54393
|
}
|
|
54197
54394
|
function resolveOmpHome(env) {
|
|
54198
54395
|
const h = os.homedir();
|
|
54199
|
-
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR :
|
|
54396
|
+
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : path9.join(h, ".omp", "agent");
|
|
54200
54397
|
}
|
|
54201
54398
|
function resolveHermesHome(env) {
|
|
54202
54399
|
const h = os.homedir();
|
|
54203
|
-
return nonEmpty2(env.HERMES_HOME) ? env.HERMES_HOME :
|
|
54400
|
+
return nonEmpty2(env.HERMES_HOME) ? env.HERMES_HOME : path9.join(h, ".hermes");
|
|
54204
54401
|
}
|
|
54205
54402
|
function resolveDshHome(env) {
|
|
54206
54403
|
const h = os.homedir();
|
|
54207
|
-
return nonEmpty2(env.DSH_HOME) ? env.DSH_HOME :
|
|
54404
|
+
return nonEmpty2(env.DSH_HOME) ? env.DSH_HOME : path9.join(h, ".dsh");
|
|
54208
54405
|
}
|
|
54209
54406
|
function parseDshSettingsYaml(text) {
|
|
54210
54407
|
const out = [];
|
|
@@ -54223,7 +54420,7 @@ function parseDshSettingsYaml(text) {
|
|
|
54223
54420
|
function readDshConfig(dshHome) {
|
|
54224
54421
|
let text;
|
|
54225
54422
|
try {
|
|
54226
|
-
text =
|
|
54423
|
+
text = fs5.readFileSync(path9.join(dshHome, "settings.yaml"), "utf8");
|
|
54227
54424
|
} catch {
|
|
54228
54425
|
return { baseUrls: [] };
|
|
54229
54426
|
}
|
|
@@ -54231,8 +54428,8 @@ function readDshConfig(dshHome) {
|
|
|
54231
54428
|
}
|
|
54232
54429
|
function readClaudeSettings(homeDir, cwd, env = process.env) {
|
|
54233
54430
|
const files = [
|
|
54234
|
-
|
|
54235
|
-
|
|
54431
|
+
path9.join(homeDir, ".claude", "settings.json"),
|
|
54432
|
+
path9.join(cwd, ".claude", "settings.json")
|
|
54236
54433
|
];
|
|
54237
54434
|
let anthropicBaseUrl;
|
|
54238
54435
|
let model;
|
|
@@ -54305,17 +54502,17 @@ function parseCodexToml(text) {
|
|
|
54305
54502
|
return result;
|
|
54306
54503
|
}
|
|
54307
54504
|
function readCodexConfig(codexHome) {
|
|
54308
|
-
const cfgPath =
|
|
54505
|
+
const cfgPath = path9.join(codexHome, "config.toml");
|
|
54309
54506
|
let text;
|
|
54310
54507
|
try {
|
|
54311
|
-
text =
|
|
54508
|
+
text = fs5.readFileSync(cfgPath, "utf8");
|
|
54312
54509
|
} catch {
|
|
54313
54510
|
return { providers: {} };
|
|
54314
54511
|
}
|
|
54315
54512
|
return parseCodexToml(text);
|
|
54316
54513
|
}
|
|
54317
54514
|
function readPiConfig(piHome) {
|
|
54318
|
-
const cfgPath =
|
|
54515
|
+
const cfgPath = path9.join(piHome, "models.json");
|
|
54319
54516
|
const obj = readJsonObject(cfgPath);
|
|
54320
54517
|
const providers = {};
|
|
54321
54518
|
const rawProviders = obj?.providers;
|
|
@@ -54396,10 +54593,10 @@ function parseOmpYaml(text) {
|
|
|
54396
54593
|
return result;
|
|
54397
54594
|
}
|
|
54398
54595
|
function readOmpConfig(ompHome) {
|
|
54399
|
-
const cfgPath =
|
|
54596
|
+
const cfgPath = path9.join(ompHome, "models.yml");
|
|
54400
54597
|
let text;
|
|
54401
54598
|
try {
|
|
54402
|
-
text =
|
|
54599
|
+
text = fs5.readFileSync(cfgPath, "utf8");
|
|
54403
54600
|
} catch {
|
|
54404
54601
|
return { providers: {} };
|
|
54405
54602
|
}
|
|
@@ -54472,10 +54669,10 @@ function parseHermesYaml(text) {
|
|
|
54472
54669
|
return result;
|
|
54473
54670
|
}
|
|
54474
54671
|
function readHermesConfig(hermesHome) {
|
|
54475
|
-
const cfgPath =
|
|
54672
|
+
const cfgPath = path9.join(hermesHome, "config.yaml");
|
|
54476
54673
|
let text;
|
|
54477
54674
|
try {
|
|
54478
|
-
text =
|
|
54675
|
+
text = fs5.readFileSync(cfgPath, "utf8");
|
|
54479
54676
|
} catch {
|
|
54480
54677
|
return { providers: {} };
|
|
54481
54678
|
}
|
|
@@ -54483,13 +54680,13 @@ function readHermesConfig(hermesHome) {
|
|
|
54483
54680
|
}
|
|
54484
54681
|
function resolveOpencodeConfigFile(env) {
|
|
54485
54682
|
if (nonEmpty2(env.OPENCODE_CONFIG)) return env.OPENCODE_CONFIG;
|
|
54486
|
-
const xdg2 = nonEmpty2(env.XDG_CONFIG_HOME) ? env.XDG_CONFIG_HOME :
|
|
54487
|
-
return
|
|
54683
|
+
const xdg2 = nonEmpty2(env.XDG_CONFIG_HOME) ? env.XDG_CONFIG_HOME : path9.join(os.homedir(), ".config");
|
|
54684
|
+
return path9.join(xdg2, "opencode", "opencode.json");
|
|
54488
54685
|
}
|
|
54489
54686
|
function readOpencodeConfig(file) {
|
|
54490
54687
|
let text;
|
|
54491
54688
|
try {
|
|
54492
|
-
text =
|
|
54689
|
+
text = fs5.readFileSync(file, "utf8");
|
|
54493
54690
|
} catch {
|
|
54494
54691
|
return { providers: {} };
|
|
54495
54692
|
}
|
|
@@ -54546,10 +54743,10 @@ function parseZcodeConfig(obj) {
|
|
|
54546
54743
|
return result;
|
|
54547
54744
|
}
|
|
54548
54745
|
function readZcodeConfig(zcodeHome) {
|
|
54549
|
-
const cfgPath =
|
|
54746
|
+
const cfgPath = path9.join(zcodeHome, "v2", "config.json");
|
|
54550
54747
|
let txt;
|
|
54551
54748
|
try {
|
|
54552
|
-
txt =
|
|
54749
|
+
txt = fs5.readFileSync(cfgPath, "utf8");
|
|
54553
54750
|
} catch {
|
|
54554
54751
|
return { providers: {} };
|
|
54555
54752
|
}
|
|
@@ -54565,10 +54762,10 @@ function loadClientConfig(env, cwd) {
|
|
|
54565
54762
|
const home = os.homedir();
|
|
54566
54763
|
const config = {};
|
|
54567
54764
|
config.claude = readClaudeSettings(home, cwd, env);
|
|
54568
|
-
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME :
|
|
54765
|
+
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path9.join(home, ".codex");
|
|
54569
54766
|
config.codex = readCodexConfig(codexHome);
|
|
54570
54767
|
config.pi = readPiConfig(resolvePiHome(env));
|
|
54571
|
-
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR :
|
|
54768
|
+
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path9.join(home, ".zcode");
|
|
54572
54769
|
config.zcode = readZcodeConfig(zcodeHome);
|
|
54573
54770
|
config.omp = readOmpConfig(resolveOmpHome(env));
|
|
54574
54771
|
config.opencode = readOpencodeConfig(resolveOpencodeConfigFile(env));
|
|
@@ -54628,21 +54825,21 @@ function extractHttpsHosts(config) {
|
|
|
54628
54825
|
}
|
|
54629
54826
|
function configFilePaths(env) {
|
|
54630
54827
|
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 :
|
|
54828
|
+
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path10.join(home, ".codex");
|
|
54829
|
+
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path10.join(home, ".zcode");
|
|
54633
54830
|
return [
|
|
54634
|
-
|
|
54635
|
-
|
|
54636
|
-
|
|
54637
|
-
|
|
54638
|
-
|
|
54831
|
+
path10.join(home, ".claude", "settings.json"),
|
|
54832
|
+
path10.join(process.cwd(), ".claude", "settings.json"),
|
|
54833
|
+
path10.join(codexHome, "config.toml"),
|
|
54834
|
+
path10.join(resolvePiHome(env), "models.json"),
|
|
54835
|
+
path10.join(zcodeHome, "v2", "config.json")
|
|
54639
54836
|
];
|
|
54640
54837
|
}
|
|
54641
54838
|
function readMtimes(paths) {
|
|
54642
54839
|
const mtimes = /* @__PURE__ */ new Map();
|
|
54643
54840
|
for (const p2 of paths) {
|
|
54644
54841
|
try {
|
|
54645
|
-
const st2 =
|
|
54842
|
+
const st2 = fs6.statSync(p2);
|
|
54646
54843
|
mtimes.set(p2, st2.mtimeMs);
|
|
54647
54844
|
} catch {
|
|
54648
54845
|
}
|
|
@@ -54810,6 +55007,108 @@ function readMitmUpstream(socket) {
|
|
|
54810
55007
|
return socket[MITM_UPSTREAM_KEY];
|
|
54811
55008
|
}
|
|
54812
55009
|
|
|
55010
|
+
// src/tunnel-guard.ts
|
|
55011
|
+
import { lookup } from "dns/promises";
|
|
55012
|
+
import { networkInterfaces } from "os";
|
|
55013
|
+
var BILI_TUNNEL_HEADER = "x-bili-tunnel";
|
|
55014
|
+
function parseIpLiteral(s3) {
|
|
55015
|
+
const t = s3.trim().toLowerCase();
|
|
55016
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(t)) return t;
|
|
55017
|
+
if (t.includes(":")) return t;
|
|
55018
|
+
return null;
|
|
55019
|
+
}
|
|
55020
|
+
function classifyIp(ip) {
|
|
55021
|
+
const lit = parseIpLiteral(ip);
|
|
55022
|
+
if (!lit) return "public";
|
|
55023
|
+
if (lit.includes(":")) {
|
|
55024
|
+
if (lit === "::1" || lit === "::") return "loopback";
|
|
55025
|
+
const mapped = lit.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
55026
|
+
if (mapped) return classifyIp(mapped[1]);
|
|
55027
|
+
if (lit.startsWith("fe8") || lit.startsWith("fe9") || lit.startsWith("fea") || lit.startsWith("feb")) return "linkLocal";
|
|
55028
|
+
if (lit.startsWith("fc") || lit.startsWith("fd")) return "private";
|
|
55029
|
+
return "public";
|
|
55030
|
+
}
|
|
55031
|
+
const parts = lit.split(".").map(Number);
|
|
55032
|
+
const [a, b2] = parts;
|
|
55033
|
+
if (a === 127) return "loopback";
|
|
55034
|
+
if (a === 169 && b2 === 254) return "linkLocal";
|
|
55035
|
+
if (a === 10 || a === 0) return "private";
|
|
55036
|
+
if (a === 172 && b2 >= 16 && b2 <= 31) return "private";
|
|
55037
|
+
if (a === 192 && b2 === 168) return "private";
|
|
55038
|
+
if (a === 100 && b2 >= 64 && b2 <= 127) return "private";
|
|
55039
|
+
return "public";
|
|
55040
|
+
}
|
|
55041
|
+
var dnsResolveHost = async (host) => {
|
|
55042
|
+
const res = await lookup(host, { all: true, family: 0 });
|
|
55043
|
+
return res.map((r) => r.address);
|
|
55044
|
+
};
|
|
55045
|
+
var localAddrCache;
|
|
55046
|
+
function localMachineIps() {
|
|
55047
|
+
const now = Date.now();
|
|
55048
|
+
if (!localAddrCache || now - localAddrCache.at > 3e4) {
|
|
55049
|
+
const ips = /* @__PURE__ */ new Set(["127.0.0.1", "::1"]);
|
|
55050
|
+
for (const list of Object.values(networkInterfaces())) {
|
|
55051
|
+
for (const ni2 of list ?? []) {
|
|
55052
|
+
if (ni2.address) ips.add(ni2.address.toLowerCase());
|
|
55053
|
+
}
|
|
55054
|
+
}
|
|
55055
|
+
for (let i = 0; i <= 255; i++) ips.add(`127.0.0.${i}`);
|
|
55056
|
+
localAddrCache = { at: now, ips };
|
|
55057
|
+
}
|
|
55058
|
+
return localAddrCache.ips;
|
|
55059
|
+
}
|
|
55060
|
+
function allowlistHit(host, port, allowlist) {
|
|
55061
|
+
const h = host.toLowerCase();
|
|
55062
|
+
const hp = `${h}:${port}`;
|
|
55063
|
+
return allowlist.some((e) => e === h || e === hp);
|
|
55064
|
+
}
|
|
55065
|
+
async function checkTunnelDestination(origin, ctx) {
|
|
55066
|
+
let u2;
|
|
55067
|
+
try {
|
|
55068
|
+
u2 = new URL(origin);
|
|
55069
|
+
} catch {
|
|
55070
|
+
return { ok: false, code: "unresolvable", message: `invalid tunnel destination ${origin}` };
|
|
55071
|
+
}
|
|
55072
|
+
const host = u2.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
55073
|
+
const port = u2.port ? Number(u2.port) : u2.protocol === "https:" ? 443 : 80;
|
|
55074
|
+
let ips;
|
|
55075
|
+
const literal = parseIpLiteral(host);
|
|
55076
|
+
if (literal) {
|
|
55077
|
+
ips = [literal];
|
|
55078
|
+
} else {
|
|
55079
|
+
try {
|
|
55080
|
+
ips = await (ctx.resolveHost ?? dnsResolveHost)(host);
|
|
55081
|
+
} catch {
|
|
55082
|
+
return { ok: false, code: "unresolvable", message: `cannot resolve tunnel destination ${host}` };
|
|
55083
|
+
}
|
|
55084
|
+
if (ips.length === 0) return { ok: false, code: "unresolvable", message: `no addresses for tunnel destination ${host}` };
|
|
55085
|
+
}
|
|
55086
|
+
if (ctx.selfPort !== void 0 && port === ctx.selfPort) {
|
|
55087
|
+
const mine = (ctx.localIps ?? localMachineIps)();
|
|
55088
|
+
if (ips.some((ip) => mine.has(ip.toLowerCase()) || mine.has(`::ffff:${ip.toLowerCase()}`))) {
|
|
55089
|
+
return { ok: false, code: "self", message: "the bili tunnel may not target the proxy itself" };
|
|
55090
|
+
}
|
|
55091
|
+
}
|
|
55092
|
+
const classes = ips.map((ip) => classifyIp(ip));
|
|
55093
|
+
if (classes.includes("linkLocal")) {
|
|
55094
|
+
return { ok: false, code: "linkLocal", message: "link-local / metadata destinations are blocked from the bili tunnel" };
|
|
55095
|
+
}
|
|
55096
|
+
if (!classes.every((c) => c === "public")) {
|
|
55097
|
+
if (ctx.clientLoopback) return { ok: true };
|
|
55098
|
+
if (allowlistHit(host, port, ctx.allowlist)) return { ok: true };
|
|
55099
|
+
return {
|
|
55100
|
+
ok: false,
|
|
55101
|
+
code: "privateRemote",
|
|
55102
|
+
message: `tunnel destination ${host} resolves to a loopback/private address; remote clients may only reach it via BILI_TUNNEL_ALLOWED_HOSTS`
|
|
55103
|
+
};
|
|
55104
|
+
}
|
|
55105
|
+
return { ok: true };
|
|
55106
|
+
}
|
|
55107
|
+
function tunnelAllowlistFromEnv(env = process.env) {
|
|
55108
|
+
const raw = env.BILI_TUNNEL_ALLOWED_HOSTS ?? "";
|
|
55109
|
+
return raw.split(",").map((s3) => s3.trim().toLowerCase()).filter((s3) => s3.length > 0);
|
|
55110
|
+
}
|
|
55111
|
+
|
|
54813
55112
|
// src/content-encoding.ts
|
|
54814
55113
|
import { promisify } from "util";
|
|
54815
55114
|
import { brotliDecompress, gunzip, inflate, inflateRaw } from "zlib";
|
|
@@ -55652,7 +55951,7 @@ function resolveUpstream(_opts, reqUrl, req) {
|
|
|
55652
55951
|
if (rest.startsWith("http://") || rest.startsWith("https://")) {
|
|
55653
55952
|
try {
|
|
55654
55953
|
const u2 = new URL(rest);
|
|
55655
|
-
return { upstream: `${u2.protocol}//${u2.host}`, rewrittenUrl: rest, explicitProtocol };
|
|
55954
|
+
return { upstream: `${u2.protocol}//${u2.host}`, rewrittenUrl: rest, explicitProtocol, tunnel: true };
|
|
55656
55955
|
} catch {
|
|
55657
55956
|
}
|
|
55658
55957
|
}
|
|
@@ -55664,17 +55963,20 @@ async function startServer(opts) {
|
|
|
55664
55963
|
const core = createCore();
|
|
55665
55964
|
const config = opts.kernelConfig;
|
|
55666
55965
|
const log2 = (level, msg) => logMsg(opts, level, msg);
|
|
55667
|
-
const instanceId =
|
|
55966
|
+
const instanceId = randomUUID4();
|
|
55967
|
+
const instanceStartedAt = Date.now();
|
|
55668
55968
|
await initSessions();
|
|
55669
55969
|
loadConversations();
|
|
55670
55970
|
log2("info", `[persist] ${getStore().enabled ? "enabled" : "disabled"}`);
|
|
55971
|
+
const tunnelAllowlist = tunnelAllowlistFromEnv();
|
|
55972
|
+
if (tunnelAllowlist.length > 0) log2("info", `[tunnel] remote-client allowlist: ${tunnelAllowlist.join(", ")}`);
|
|
55671
55973
|
if (filePath) {
|
|
55672
55974
|
log2("info", `[log] writing to ${filePath}`);
|
|
55673
55975
|
}
|
|
55674
55976
|
void loadRegistry();
|
|
55675
55977
|
const server = http.createServer(async (req, res) => {
|
|
55676
55978
|
try {
|
|
55677
|
-
await handle(req, res, opts, core, config, log2, instanceId);
|
|
55979
|
+
await handle(req, res, opts, core, config, log2, instanceId, instanceStartedAt);
|
|
55678
55980
|
} catch (err2) {
|
|
55679
55981
|
const msg = String(err2);
|
|
55680
55982
|
log2("error", msg);
|
|
@@ -55705,33 +56007,65 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
55705
56007
|
const allowRemoteConnect = opts.host === "0.0.0.0" || opts.host === "::" || !isLoopbackAddress(opts.host);
|
|
55706
56008
|
setupMitm(server, opts.mitm.domains, (msg) => log2("info", msg), (host) => resolveProxy(opts.routes, opts.proxy, `https://${host}`, opts.proxyFallback), allowRemoteConnect);
|
|
55707
56009
|
}
|
|
55708
|
-
|
|
56010
|
+
const launchToken = process.env.BILI_LAUNCH_TOKEN?.trim();
|
|
56011
|
+
const MAX_LISTEN_ATTEMPTS = 17;
|
|
56012
|
+
let listenAttempts = 0;
|
|
56013
|
+
let lastTriedPort = opts.port;
|
|
56014
|
+
const announceListening = () => {
|
|
56015
|
+
const actualPort = server.address() === null ? opts.port : server.address().port;
|
|
55709
56016
|
const nonLoopbackBind = opts.host === "0.0.0.0" || opts.host === "::" || !isLoopbackAddress(opts.host);
|
|
55710
56017
|
const displayHost = nonLoopbackBind ? opts.host : opts.host === "0.0.0.0" ? "localhost" : opts.host;
|
|
56018
|
+
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;
|
|
56019
|
+
const origin = `http://${originHost}:${actualPort}`;
|
|
55711
56020
|
try {
|
|
55712
|
-
|
|
55713
|
-
|
|
55714
|
-
|
|
55715
|
-
|
|
56021
|
+
fs7.mkdirSync(stateDir(), { recursive: true });
|
|
56022
|
+
atomicWriteInstanceFile({
|
|
56023
|
+
origin,
|
|
56024
|
+
instanceId,
|
|
56025
|
+
pid: process.pid,
|
|
56026
|
+
startedAt: instanceStartedAt,
|
|
56027
|
+
host: opts.host,
|
|
56028
|
+
port: actualPort,
|
|
56029
|
+
passthrough: opts.passthrough,
|
|
56030
|
+
mitmDomains: opts.mitm.enabled ? opts.mitm.domains : [],
|
|
56031
|
+
modelWindows: { ...LAUNCHER_MODEL_WINDOWS },
|
|
56032
|
+
launchToken: launchToken || void 0
|
|
56033
|
+
});
|
|
55716
56034
|
} catch {
|
|
55717
56035
|
}
|
|
56036
|
+
registerInstanceAndWarn(
|
|
56037
|
+
{ instanceId, pid: process.pid, port: actualPort, origin, startedAt: instanceStartedAt },
|
|
56038
|
+
(msg) => log2("warn", `[instances] ${msg}`)
|
|
56039
|
+
);
|
|
55718
56040
|
const nOverrides = Object.keys(opts.routes).length;
|
|
55719
56041
|
log2(
|
|
55720
56042
|
"info",
|
|
55721
|
-
`acp-proxy listening on http://${displayHost}:${
|
|
56043
|
+
`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
56044
|
);
|
|
55723
56045
|
if (nonLoopbackBind) {
|
|
55724
56046
|
log2(
|
|
55725
56047
|
"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>:${
|
|
56048
|
+
`[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
56049
|
);
|
|
55728
56050
|
}
|
|
55729
56051
|
if (opts.debug) {
|
|
55730
56052
|
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
56053
|
}
|
|
55732
|
-
}
|
|
56054
|
+
};
|
|
56055
|
+
const attemptListen = (port) => {
|
|
56056
|
+
lastTriedPort = port;
|
|
56057
|
+
server.listen(port, opts.host, announceListening);
|
|
56058
|
+
};
|
|
56059
|
+
attemptListen(opts.port);
|
|
55733
56060
|
server.on("error", (err2) => {
|
|
55734
|
-
|
|
56061
|
+
if (err2.code === "EADDRINUSE" && launchToken && listenAttempts < MAX_LISTEN_ATTEMPTS) {
|
|
56062
|
+
listenAttempts += 1;
|
|
56063
|
+
const next = listenAttempts === MAX_LISTEN_ATTEMPTS ? 0 : lastTriedPort + 1;
|
|
56064
|
+
log2("warn", `port ${lastTriedPort} busy \u2014 ${next === 0 ? "retrying on an ephemeral port" : `retrying on port ${next}`}`);
|
|
56065
|
+
attemptListen(next);
|
|
56066
|
+
return;
|
|
56067
|
+
}
|
|
56068
|
+
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
56069
|
log2("error", `listen failed: ${err2.code ?? ""} ${err2.message}${hint}`);
|
|
55736
56070
|
shuttingDown = true;
|
|
55737
56071
|
server.close();
|
|
@@ -55748,24 +56082,24 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
55748
56082
|
log2("error", `unhandledRejection: ${String(reason)}`);
|
|
55749
56083
|
});
|
|
55750
56084
|
let shuttingDown = false;
|
|
56085
|
+
const finishShutdown = () => {
|
|
56086
|
+
clearProxyInstanceFile(instanceId);
|
|
56087
|
+
unregisterInstance(instanceId);
|
|
56088
|
+
closeLogger();
|
|
56089
|
+
process.exit(0);
|
|
56090
|
+
};
|
|
55751
56091
|
const shutdown = (sig) => {
|
|
55752
56092
|
if (shuttingDown) return;
|
|
55753
56093
|
shuttingDown = true;
|
|
55754
56094
|
log2("info", `${sig} received \u2014 flushing sessions\u2026`);
|
|
55755
56095
|
server.close(() => {
|
|
55756
56096
|
flushConversations();
|
|
55757
|
-
void flushAllSessions().finally(
|
|
55758
|
-
closeLogger();
|
|
55759
|
-
process.exit(0);
|
|
55760
|
-
});
|
|
56097
|
+
void flushAllSessions().finally(finishShutdown);
|
|
55761
56098
|
});
|
|
55762
56099
|
setTimeout(() => {
|
|
55763
56100
|
log2("warn", "shutdown grace window elapsed; forcing exit");
|
|
55764
56101
|
flushConversations();
|
|
55765
|
-
void flushAllSessions().finally(
|
|
55766
|
-
closeLogger();
|
|
55767
|
-
process.exit(0);
|
|
55768
|
-
});
|
|
56102
|
+
void flushAllSessions().finally(finishShutdown);
|
|
55769
56103
|
}, 1e4).unref?.();
|
|
55770
56104
|
};
|
|
55771
56105
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
@@ -55773,6 +56107,13 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
55773
56107
|
if (process.platform === "win32") {
|
|
55774
56108
|
process.on("SIGBREAK", () => shutdown("SIGBREAK"));
|
|
55775
56109
|
}
|
|
56110
|
+
const parentPid = Number.parseInt(process.env.BILI_PARENT_PID ?? "", 10);
|
|
56111
|
+
if (Number.isInteger(parentPid) && parentPid > 0 && parentPid !== process.pid) {
|
|
56112
|
+
const watcher = setInterval(() => {
|
|
56113
|
+
if (!isPidAlive(parentPid)) shutdown(`parent-gone (pid ${parentPid})`);
|
|
56114
|
+
}, 2e3);
|
|
56115
|
+
watcher.unref?.();
|
|
56116
|
+
}
|
|
55776
56117
|
return server;
|
|
55777
56118
|
}
|
|
55778
56119
|
function isTrustedAdminOrigin(origin, host, trustedHosts) {
|
|
@@ -55799,8 +56140,13 @@ function adminTrustedHosts(bindHost, port) {
|
|
|
55799
56140
|
}
|
|
55800
56141
|
return set;
|
|
55801
56142
|
}
|
|
55802
|
-
async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
56143
|
+
async function handle(req, res, opts, core, config, log2, instanceId, instanceStartedAt) {
|
|
55803
56144
|
const isAdminPath = req.url === "/__bili/" || req.url?.startsWith("/__bili/") || req.url === "/__acp/" || req.url?.startsWith("/__acp/");
|
|
56145
|
+
if (isAdminPath && headerValue2(req, BILI_TUNNEL_HEADER) !== void 0) {
|
|
56146
|
+
res.writeHead(403, { "content-type": "application/json" });
|
|
56147
|
+
res.end(JSON.stringify({ error: "management endpoints are not reachable through the bili tunnel" }));
|
|
56148
|
+
return;
|
|
56149
|
+
}
|
|
55804
56150
|
if (isAdminPath && !isLoopbackAddress(req.socket.remoteAddress)) {
|
|
55805
56151
|
res.writeHead(403, { "content-type": "application/json" });
|
|
55806
56152
|
res.end(JSON.stringify({ error: "management endpoints are loopback-only; access denied for " + (req.socket.remoteAddress ?? "unknown") }));
|
|
@@ -55825,7 +56171,7 @@ async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
|
55825
56171
|
}
|
|
55826
56172
|
if (req.method === "GET" && req.url === "/__bili/health") {
|
|
55827
56173
|
res.writeHead(200, { "content-type": "application/json" });
|
|
55828
|
-
res.end(JSON.stringify({ ok: true, upstream: opts.upstream }));
|
|
56174
|
+
res.end(JSON.stringify({ ok: true, upstream: opts.upstream, instanceId, pid: process.pid, startedAt: instanceStartedAt }));
|
|
55829
56175
|
return;
|
|
55830
56176
|
}
|
|
55831
56177
|
if (req.method === "GET" && req.url === "/__bili/") {
|
|
@@ -55946,6 +56292,19 @@ async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
|
55946
56292
|
urlPath = url.split("?", 2)[0];
|
|
55947
56293
|
responsesCompact = urlPath.endsWith("/responses/compact");
|
|
55948
56294
|
route = resolveUpstream(opts, req.url ?? "", req);
|
|
56295
|
+
if (route?.tunnel) {
|
|
56296
|
+
const verdict = await checkTunnelDestination(route.upstream, {
|
|
56297
|
+
selfPort: req.socket.localPort ?? void 0,
|
|
56298
|
+
clientLoopback: isLoopbackAddress(req.socket.remoteAddress),
|
|
56299
|
+
allowlist: tunnelAllowlistFromEnv()
|
|
56300
|
+
});
|
|
56301
|
+
if (!verdict.ok) {
|
|
56302
|
+
log2("warn", `[tunnel] denied ${maskUrlsInText(route.upstream)}: ${verdict.message}`);
|
|
56303
|
+
res.writeHead(403, { "content-type": "application/json" });
|
|
56304
|
+
res.end(JSON.stringify({ error: verdict.message, code: "tunnel_destination_denied", detail: verdict.code }));
|
|
56305
|
+
return;
|
|
56306
|
+
}
|
|
56307
|
+
}
|
|
55949
56308
|
upstreamOrigin = route ? route.upstream : /^https?:\/\//i.test(url) ? new URL(url).origin : opts.upstream;
|
|
55950
56309
|
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
56310
|
if (protocol !== null && bodyBuffer.length > 0) {
|
|
@@ -55989,14 +56348,14 @@ async function handle(req, res, opts, core, config, log2, instanceId) {
|
|
|
55989
56348
|
try {
|
|
55990
56349
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
55991
56350
|
try {
|
|
55992
|
-
|
|
56351
|
+
fs7.mkdirSync(rawDir, { recursive: true });
|
|
55993
56352
|
} catch {
|
|
55994
56353
|
}
|
|
55995
56354
|
const hdrs = maskHeadersForLog(
|
|
55996
56355
|
Object.fromEntries(Object.entries(req.headers).map(([k2, v2]) => [k2, Array.isArray(v2) ? v2.join(",") : String(v2)]))
|
|
55997
56356
|
);
|
|
55998
56357
|
const hdrText = Object.entries(hdrs).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
55999
|
-
|
|
56358
|
+
fs7.writeFileSync(`${rawDir}/${Date.now()}-INCOMING.txt`, `${req.method} ${maskUrlsInText(req.url ?? "")}
|
|
56000
56359
|
${hdrText}
|
|
56001
56360
|
|
|
56002
56361
|
${bodyBuffer.toString("utf8")}`);
|
|
@@ -56262,6 +56621,10 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
56262
56621
|
let rebuiltMessages = parsed.messages;
|
|
56263
56622
|
let systemOut = parsed.system;
|
|
56264
56623
|
let toolsOut = parsed.tools;
|
|
56624
|
+
const strippedPanels = stripAcpPanelMessages(parsed.messages);
|
|
56625
|
+
if (strippedPanels > 0) {
|
|
56626
|
+
log2("info", `[${sessionId}] stripped ${strippedPanels} ACP panel message(s) before projection (UI-only, issue #359)`);
|
|
56627
|
+
}
|
|
56265
56628
|
try {
|
|
56266
56629
|
const { msgs, cacheControls } = anthropicToCore(parsed);
|
|
56267
56630
|
originalMessages = msgs;
|
|
@@ -56286,7 +56649,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
56286
56649
|
if (injectTools) {
|
|
56287
56650
|
toolsOut = injectTool(parsed.tools);
|
|
56288
56651
|
}
|
|
56289
|
-
if (opts.compress.injectNudge && turn.nudge?.shouldInject) {
|
|
56652
|
+
if (opts.compress.injectNudge && !pluginMode && turn.nudge?.shouldInject) {
|
|
56290
56653
|
try {
|
|
56291
56654
|
const rendered = renderNudgeText(turn.nudge, prompts);
|
|
56292
56655
|
if (rendered.text) {
|
|
@@ -56319,6 +56682,10 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
56319
56682
|
const isTitleGen = maxTokens <= 200;
|
|
56320
56683
|
const shouldInject = opts.compress.injectTool && !isTitleGen;
|
|
56321
56684
|
const injectTools = shouldInject && !pluginMode;
|
|
56685
|
+
const strippedPanels = stripAcpPanelMessages(parsed.messages);
|
|
56686
|
+
if (strippedPanels > 0) {
|
|
56687
|
+
log2("info", `[${sessionId}] stripped ${strippedPanels} ACP panel message(s) before projection (UI-only, issue #359)`);
|
|
56688
|
+
}
|
|
56322
56689
|
try {
|
|
56323
56690
|
const { msgs, systemText } = openaiToCore(parsed);
|
|
56324
56691
|
openaiSystemText = systemText;
|
|
@@ -56338,7 +56705,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
56338
56705
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
56339
56706
|
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
56340
56707
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
56341
|
-
rebuiltMessages =
|
|
56708
|
+
rebuiltMessages = systemToUser(coreToOpenai(processedMessages));
|
|
56342
56709
|
const sysParts = [];
|
|
56343
56710
|
if (systemText) sysParts.push(systemText);
|
|
56344
56711
|
if (shouldInject) sysParts.push(buildCompressSystemPrompt(prompts));
|
|
@@ -56346,7 +56713,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
56346
56713
|
if (injectTools) {
|
|
56347
56714
|
toolsOut = injectOpenaiTool(parsed.tools);
|
|
56348
56715
|
}
|
|
56349
|
-
if (opts.compress.injectNudge && turn.nudge?.shouldInject && shouldInject) {
|
|
56716
|
+
if (opts.compress.injectNudge && !pluginMode && turn.nudge?.shouldInject && shouldInject) {
|
|
56350
56717
|
try {
|
|
56351
56718
|
const rendered = renderNudgeText(turn.nudge, prompts);
|
|
56352
56719
|
if (rendered.text) {
|
|
@@ -56400,6 +56767,10 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
56400
56767
|
if (droppedEmpty > 0) {
|
|
56401
56768
|
log2("info", `[${sessionId}] dropped ${droppedEmpty} whitespace-only message item(s) before projection (flattened-turn artifact)`);
|
|
56402
56769
|
}
|
|
56770
|
+
const strippedPanels = stripAcpPanelResponsesInput(parsed.input);
|
|
56771
|
+
if (strippedPanels > 0) {
|
|
56772
|
+
log2("info", `[${sessionId}] stripped ${strippedPanels} ACP panel message(s) before projection (UI-only, issue #359)`);
|
|
56773
|
+
}
|
|
56403
56774
|
const shouldInject = opts.compress.injectTool;
|
|
56404
56775
|
const injectTools = shouldInject && !pluginMode;
|
|
56405
56776
|
const isCompactionTrigger = hasCompactionTrigger(parsed.input);
|
|
@@ -56440,7 +56811,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
56440
56811
|
const devContent = [...projection.systemParts, ...forgedSummaries].join("\n\n---\n\n");
|
|
56441
56812
|
rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
|
|
56442
56813
|
}
|
|
56443
|
-
if (opts.compress.injectNudge && turn.nudge?.shouldInject && shouldInject && !isCompactionTrigger) {
|
|
56814
|
+
if (opts.compress.injectNudge && !pluginMode && turn.nudge?.shouldInject && shouldInject && !isCompactionTrigger) {
|
|
56444
56815
|
try {
|
|
56445
56816
|
const rendered = renderNudgeText(turn.nudge, prompts);
|
|
56446
56817
|
if (rendered.text) {
|
|
@@ -56675,6 +57046,7 @@ function buildForwardTarget(req, opts, route, affinity, hopMarker) {
|
|
|
56675
57046
|
headers[k2] = Array.isArray(v2) ? v2.join(", ") : v2;
|
|
56676
57047
|
}
|
|
56677
57048
|
if (hopMarker !== void 0) headers[BILI_HOP_HEADER] = hopMarker;
|
|
57049
|
+
if (route?.tunnel) headers[BILI_TUNNEL_HEADER] = "1";
|
|
56678
57050
|
headers["host"] = new URL(upstreamUrl).host;
|
|
56679
57051
|
const betaKey = Object.keys(headers).find((h) => h.toLowerCase() === "x-codex-beta-features");
|
|
56680
57052
|
if (betaKey) {
|
|
@@ -56786,16 +57158,16 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
56786
57158
|
if (bodyDumpEnabled() && process.env.ACP_DUMP_REQ !== "0") {
|
|
56787
57159
|
const dumpDir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
|
|
56788
57160
|
try {
|
|
56789
|
-
|
|
57161
|
+
fs7.mkdirSync(dumpDir, { recursive: true });
|
|
56790
57162
|
} catch {
|
|
56791
57163
|
}
|
|
56792
57164
|
const sid = prepared?.session.id ?? "unknown";
|
|
56793
57165
|
const out = `${dumpDir}/req-${Date.now()}-${safeSessionId(sid)}.json`;
|
|
56794
57166
|
try {
|
|
56795
57167
|
const pretty = JSON.stringify(JSON.parse(body), null, 2);
|
|
56796
|
-
|
|
57168
|
+
fs7.writeFileSync(out, pretty);
|
|
56797
57169
|
} catch {
|
|
56798
|
-
|
|
57170
|
+
fs7.writeFileSync(out, body);
|
|
56799
57171
|
}
|
|
56800
57172
|
log2("info", `[debug] forwarded body written to ${out}`);
|
|
56801
57173
|
}
|
|
@@ -56815,7 +57187,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
56815
57187
|
const rawBase = bodyDumpEnabled() ? (() => {
|
|
56816
57188
|
try {
|
|
56817
57189
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
56818
|
-
|
|
57190
|
+
fs7.mkdirSync(rawDir, { recursive: true });
|
|
56819
57191
|
return `${rawDir}/${Date.now()}-${safeSessionId(prepared?.session.id)}`;
|
|
56820
57192
|
} catch {
|
|
56821
57193
|
return "";
|
|
@@ -56826,7 +57198,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
56826
57198
|
const hdrText = Object.entries(maskHeadersForLog(headers)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
56827
57199
|
const bodyText = req.method === "GET" || req.method === "HEAD" ? "" : typeof body === "string" ? body : Buffer.from(body).toString("utf8");
|
|
56828
57200
|
const reqPath = `${rawBase}-REQ.txt`;
|
|
56829
|
-
|
|
57201
|
+
fs7.writeFileSync(reqPath, `${req.method ?? "POST"} ${maskUrlForLog(upstreamUrl)}
|
|
56830
57202
|
${hdrText}
|
|
56831
57203
|
|
|
56832
57204
|
${bodyText}`);
|
|
@@ -56876,7 +57248,7 @@ ${bodyText}`);
|
|
|
56876
57248
|
try {
|
|
56877
57249
|
const hdrText = Object.entries(maskHeadersForLog(respHeaders)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
56878
57250
|
const resPath = `${rawBase}-RES.txt`;
|
|
56879
|
-
|
|
57251
|
+
fs7.writeFileSync(resPath, `${upstream.status}
|
|
56880
57252
|
${hdrText}
|
|
56881
57253
|
`);
|
|
56882
57254
|
log2("info", `[debug] RAW response dump: ${resPath}`);
|
|
@@ -59175,7 +59547,7 @@ var hr = /* @__PURE__ */ Symbol("entry");
|
|
|
59175
59547
|
var cs = /* @__PURE__ */ Symbol("entryOpt");
|
|
59176
59548
|
var ui = /* @__PURE__ */ Symbol("writeEntryClass");
|
|
59177
59549
|
var lr = /* @__PURE__ */ Symbol("write");
|
|
59178
|
-
var
|
|
59550
|
+
var fs8 = /* @__PURE__ */ Symbol("ondrain");
|
|
59179
59551
|
var wt = class extends A {
|
|
59180
59552
|
sync = false;
|
|
59181
59553
|
opt;
|
|
@@ -59209,8 +59581,8 @@ var wt = class extends A {
|
|
|
59209
59581
|
if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
|
|
59210
59582
|
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
59583
|
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[
|
|
59584
|
+
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs8]()), this.on("resume", () => e.resume());
|
|
59585
|
+
} else this.on("drain", this[fs8]);
|
|
59214
59586
|
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
59587
|
}
|
|
59216
59588
|
[lr](t) {
|
|
@@ -59323,7 +59695,7 @@ var wt = class extends A {
|
|
|
59323
59695
|
this.emit("error", e);
|
|
59324
59696
|
}
|
|
59325
59697
|
}
|
|
59326
|
-
[
|
|
59698
|
+
[fs8]() {
|
|
59327
59699
|
this[Et] && this[Et].entry && this[Et].entry.resume();
|
|
59328
59700
|
}
|
|
59329
59701
|
[di](t) {
|
|
@@ -60208,12 +60580,12 @@ var To = (s3) => {
|
|
|
60208
60580
|
};
|
|
60209
60581
|
|
|
60210
60582
|
// src/update.ts
|
|
60211
|
-
import
|
|
60583
|
+
import path11 from "path";
|
|
60212
60584
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
60213
60585
|
var REGISTRY_BASE = "https://registry.npmjs.org";
|
|
60214
60586
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
60215
|
-
var THROTTLE_FILE =
|
|
60216
|
-
var LOCK_FILE =
|
|
60587
|
+
var THROTTLE_FILE = path11.join(cacheDir(), ".update-check");
|
|
60588
|
+
var LOCK_FILE = path11.join(cacheDir(), ".update-lock");
|
|
60217
60589
|
var LOCK_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
60218
60590
|
function shouldStealLock(holderAlive, ageMs) {
|
|
60219
60591
|
return !holderAlive || ageMs >= LOCK_MAX_AGE_MS;
|
|
@@ -60248,27 +60620,27 @@ async function readLastCheck() {
|
|
|
60248
60620
|
}
|
|
60249
60621
|
async function writeLastCheck(ts2) {
|
|
60250
60622
|
try {
|
|
60251
|
-
await mkdir2(
|
|
60623
|
+
await mkdir2(path11.dirname(THROTTLE_FILE), { recursive: true });
|
|
60252
60624
|
await writeFile2(THROTTLE_FILE, String(ts2), "utf-8");
|
|
60253
60625
|
} catch {
|
|
60254
60626
|
}
|
|
60255
60627
|
}
|
|
60256
60628
|
async function findInstallDir(packageName) {
|
|
60257
|
-
let dir =
|
|
60629
|
+
let dir = path11.dirname(fileURLToPath3(import.meta.url));
|
|
60258
60630
|
for (; ; ) {
|
|
60259
60631
|
try {
|
|
60260
|
-
const pkg = JSON.parse(await readFile2(
|
|
60632
|
+
const pkg = JSON.parse(await readFile2(path11.join(dir, "package.json"), "utf-8"));
|
|
60261
60633
|
if (pkg.name === packageName) return dir;
|
|
60262
60634
|
} catch {
|
|
60263
60635
|
}
|
|
60264
|
-
const parent =
|
|
60636
|
+
const parent = path11.dirname(dir);
|
|
60265
60637
|
if (parent === dir) return void 0;
|
|
60266
60638
|
dir = parent;
|
|
60267
60639
|
}
|
|
60268
60640
|
}
|
|
60269
60641
|
async function readDiskVersion(installDir) {
|
|
60270
60642
|
try {
|
|
60271
|
-
const pkg = JSON.parse(await readFile2(
|
|
60643
|
+
const pkg = JSON.parse(await readFile2(path11.join(installDir, "package.json"), "utf-8"));
|
|
60272
60644
|
return pkg.version;
|
|
60273
60645
|
} catch {
|
|
60274
60646
|
return void 0;
|
|
@@ -60305,13 +60677,13 @@ async function syntaxCheckEntry(entryAbs) {
|
|
|
60305
60677
|
} catch (e) {
|
|
60306
60678
|
return `entry unreadable: ${String(e)}`;
|
|
60307
60679
|
}
|
|
60308
|
-
const tmpCheck =
|
|
60680
|
+
const tmpCheck = path11.join(cacheDir(), ".update-syntax-check.mjs");
|
|
60309
60681
|
try {
|
|
60310
60682
|
await mkdir2(cacheDir(), { recursive: true });
|
|
60311
60683
|
await writeFile2(tmpCheck, source);
|
|
60312
60684
|
const r = await runNodeCheck(tmpCheck);
|
|
60313
60685
|
if (r.code !== 0) {
|
|
60314
|
-
return `entry does not parse (${
|
|
60686
|
+
return `entry does not parse (${path11.basename(entryAbs)}): ${r.stderr.split("\n").filter(Boolean).slice(0, 3).join(" | ").slice(0, 300)}`;
|
|
60315
60687
|
}
|
|
60316
60688
|
return null;
|
|
60317
60689
|
} finally {
|
|
@@ -60324,7 +60696,7 @@ async function syntaxCheckEntry(entryAbs) {
|
|
|
60324
60696
|
async function verifyEntries(dir, label) {
|
|
60325
60697
|
let pkg;
|
|
60326
60698
|
try {
|
|
60327
|
-
pkg = JSON.parse(await readFile2(
|
|
60699
|
+
pkg = JSON.parse(await readFile2(path11.join(dir, "package.json"), "utf-8"));
|
|
60328
60700
|
} catch (e) {
|
|
60329
60701
|
return `${label}: package.json unreadable: ${String(e)}`;
|
|
60330
60702
|
}
|
|
@@ -60334,11 +60706,11 @@ async function verifyEntries(dir, label) {
|
|
|
60334
60706
|
}
|
|
60335
60707
|
for (const rel2 of entries) {
|
|
60336
60708
|
try {
|
|
60337
|
-
await access(
|
|
60709
|
+
await access(path11.join(dir, rel2));
|
|
60338
60710
|
} catch {
|
|
60339
60711
|
return `${label}: entry missing: ${rel2}`;
|
|
60340
60712
|
}
|
|
60341
|
-
const reason = await syntaxCheckEntry(
|
|
60713
|
+
const reason = await syntaxCheckEntry(path11.join(dir, rel2));
|
|
60342
60714
|
if (reason) return `${label}: ${reason}`;
|
|
60343
60715
|
}
|
|
60344
60716
|
return null;
|
|
@@ -60543,14 +60915,14 @@ async function installViaTarball(version2, tarballUrl, installDir, integrity, sh
|
|
|
60543
60915
|
if (!v2.ok) {
|
|
60544
60916
|
return { ok: false, error: `tarball integrity verification failed: ${v2.error}` };
|
|
60545
60917
|
}
|
|
60546
|
-
const tmpFile =
|
|
60918
|
+
const tmpFile = path11.join(cacheDir(), `.update-${version2}.tgz`);
|
|
60547
60919
|
try {
|
|
60548
60920
|
await mkdir2(cacheDir(), { recursive: true });
|
|
60549
60921
|
await writeFile2(tmpFile, tgzBuffer);
|
|
60550
60922
|
} catch (e) {
|
|
60551
60923
|
return { ok: false, error: `failed to write temp file ${tmpFile}: ${String(e)}` };
|
|
60552
60924
|
}
|
|
60553
|
-
const stagingDir =
|
|
60925
|
+
const stagingDir = path11.join(cacheDir(), `.update-staging-${version2}`);
|
|
60554
60926
|
try {
|
|
60555
60927
|
await rm2(stagingDir, { recursive: true, force: true });
|
|
60556
60928
|
await mkdir2(stagingDir, { recursive: true });
|
|
@@ -60572,7 +60944,7 @@ async function installViaTarball(version2, tarballUrl, installDir, integrity, sh
|
|
|
60572
60944
|
} finally {
|
|
60573
60945
|
await rm2(tmpFile, { force: true });
|
|
60574
60946
|
}
|
|
60575
|
-
const backupDir =
|
|
60947
|
+
const backupDir = path11.join(cacheDir(), `.update-backup-${version2}`);
|
|
60576
60948
|
try {
|
|
60577
60949
|
await rm2(backupDir, { recursive: true, force: true });
|
|
60578
60950
|
await cp(installDir, backupDir, { recursive: true, force: true });
|
|
@@ -60628,14 +61000,14 @@ function startAutoUpdate(opts) {
|
|
|
60628
61000
|
}
|
|
60629
61001
|
|
|
60630
61002
|
// src/mcp.ts
|
|
60631
|
-
import
|
|
60632
|
-
import
|
|
61003
|
+
import fs9 from "fs";
|
|
61004
|
+
import path12 from "path";
|
|
60633
61005
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
60634
61006
|
var VERSION2 = (() => {
|
|
60635
61007
|
try {
|
|
60636
61008
|
const here = fileURLToPath4(import.meta.url);
|
|
60637
|
-
const pkg =
|
|
60638
|
-
return JSON.parse(
|
|
61009
|
+
const pkg = path12.join(path12.dirname(here), "..", "package.json");
|
|
61010
|
+
return JSON.parse(fs9.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
60639
61011
|
} catch {
|
|
60640
61012
|
return "dev";
|
|
60641
61013
|
}
|
|
@@ -60644,11 +61016,8 @@ var DEFAULT_PROXY_ORIGIN = "http://127.0.0.1:8787";
|
|
|
60644
61016
|
function resolveProxyOrigin() {
|
|
60645
61017
|
const fromEnv = process.env.BILI_MCP_PROXY?.trim();
|
|
60646
61018
|
if (fromEnv && fromEnv.length > 0) return fromEnv;
|
|
60647
|
-
|
|
60648
|
-
|
|
60649
|
-
if (/^https?:\/\/\S+$/.test(discovered)) return discovered;
|
|
60650
|
-
} catch {
|
|
60651
|
-
}
|
|
61019
|
+
const discovered = readProxyInstanceFile();
|
|
61020
|
+
if (discovered && /^https?:\/\/\S+$/.test(discovered.origin)) return discovered.origin;
|
|
60652
61021
|
return DEFAULT_PROXY_ORIGIN;
|
|
60653
61022
|
}
|
|
60654
61023
|
var TOOL_TIMEOUT_MS = 6e4;
|
|
@@ -60807,30 +61176,42 @@ if (process.argv[1] && /(?:^|[\\/])mcp\.(?:ts|js)$/.test(process.argv[1])) {
|
|
|
60807
61176
|
}
|
|
60808
61177
|
|
|
60809
61178
|
// src/plugin-install.ts
|
|
60810
|
-
import
|
|
60811
|
-
import
|
|
61179
|
+
import fs10 from "fs";
|
|
61180
|
+
import path13 from "path";
|
|
60812
61181
|
import os4 from "os";
|
|
60813
61182
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
60814
61183
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
61184
|
+
function proxyOriginForInstall() {
|
|
61185
|
+
const fromEnv = process.env.BILI_MCP_PROXY?.trim();
|
|
61186
|
+
if (fromEnv && fromEnv.length > 0) return fromEnv;
|
|
61187
|
+
const inst = readProxyInstanceFile();
|
|
61188
|
+
if (inst === void 0) {
|
|
61189
|
+
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");
|
|
61190
|
+
}
|
|
61191
|
+
if (isProxyInstanceFile(inst) && !isPidAlive(inst.pid)) {
|
|
61192
|
+
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`);
|
|
61193
|
+
}
|
|
61194
|
+
return inst.origin;
|
|
61195
|
+
}
|
|
60815
61196
|
var PLUGIN_AGENTS = ["pi", "omp", "claude", "codex", "opencode"];
|
|
60816
61197
|
function selfPackageRoot() {
|
|
60817
61198
|
const here = fileURLToPath5(import.meta.url);
|
|
60818
|
-
return
|
|
61199
|
+
return path13.resolve(path13.dirname(here), "..");
|
|
60819
61200
|
}
|
|
60820
61201
|
function homeFile(rel2, envOverride) {
|
|
60821
61202
|
const raw = (envOverride !== void 0 ? process.env[envOverride] : void 0)?.trim();
|
|
60822
61203
|
const base = raw && raw.length > 0 ? raw : os4.homedir();
|
|
60823
|
-
return
|
|
61204
|
+
return path13.join(base, rel2);
|
|
60824
61205
|
}
|
|
60825
61206
|
function backupOnce(file) {
|
|
60826
|
-
if (
|
|
60827
|
-
|
|
61207
|
+
if (fs10.existsSync(file) && !fs10.existsSync(`${file}.bili-bak`)) {
|
|
61208
|
+
fs10.copyFileSync(file, `${file}.bili-bak`);
|
|
60828
61209
|
}
|
|
60829
61210
|
}
|
|
60830
61211
|
function readJson(file) {
|
|
60831
61212
|
let text;
|
|
60832
61213
|
try {
|
|
60833
|
-
text =
|
|
61214
|
+
text = fs10.readFileSync(file, "utf8");
|
|
60834
61215
|
} catch (err2) {
|
|
60835
61216
|
if (err2.code === "ENOENT") return {};
|
|
60836
61217
|
throw err2;
|
|
@@ -60839,7 +61220,7 @@ function readJson(file) {
|
|
|
60839
61220
|
try {
|
|
60840
61221
|
parsed = JSON.parse(text);
|
|
60841
61222
|
} catch (err2) {
|
|
60842
|
-
throw new Error(`${file}: not valid JSON (${err2 instanceof Error ? err2.message : String(err2)}) \u2014 fix it or restore ${
|
|
61223
|
+
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
61224
|
}
|
|
60844
61225
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
60845
61226
|
throw new Error(`${file}: expected a JSON object at top level, refusing to overwrite`);
|
|
@@ -60847,18 +61228,18 @@ function readJson(file) {
|
|
|
60847
61228
|
return parsed;
|
|
60848
61229
|
}
|
|
60849
61230
|
function writeJson(file, data) {
|
|
60850
|
-
|
|
61231
|
+
fs10.mkdirSync(path13.dirname(file), { recursive: true });
|
|
60851
61232
|
backupOnce(file);
|
|
60852
|
-
|
|
61233
|
+
fs10.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
60853
61234
|
}
|
|
60854
61235
|
function requireDistFile(file) {
|
|
60855
|
-
if (!
|
|
61236
|
+
if (!fs10.existsSync(file)) {
|
|
60856
61237
|
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
61238
|
`);
|
|
60858
61239
|
}
|
|
60859
61240
|
}
|
|
60860
61241
|
function piSettingsFile() {
|
|
60861
|
-
return
|
|
61242
|
+
return path13.join(resolvePiHome(process.env), "settings.json");
|
|
60862
61243
|
}
|
|
60863
61244
|
function isPiEntry(entry, root) {
|
|
60864
61245
|
return entry === root || /^npm:billion-context(-pi)?(@|$)/.test(entry) || /(^|[/\\])node_modules[/\\]billion-context(-pi)?([\/\\]|$)/.test(entry) || /(^|[/\\])billion-context(-pi)?$/.test(entry);
|
|
@@ -60895,35 +61276,80 @@ function piStatus() {
|
|
|
60895
61276
|
const list = Array.isArray(packages) ? packages.map(String) : [];
|
|
60896
61277
|
return list.some((p2) => p2 === root) ? "installed" : "not installed";
|
|
60897
61278
|
}
|
|
61279
|
+
var OMP_ENTRY_RE = /[\\/]dist[\\/]agent[\\/]omp\.js$/;
|
|
61280
|
+
function ompExtensionItemLines(text) {
|
|
61281
|
+
const lines = text.split("\n");
|
|
61282
|
+
let keyIdx = -1;
|
|
61283
|
+
for (let i = 0; i < lines.length; i++) {
|
|
61284
|
+
if (/^extensions:(\s+(#.*)?)?$/.test(lines[i])) {
|
|
61285
|
+
if (keyIdx !== -1) return [];
|
|
61286
|
+
keyIdx = i;
|
|
61287
|
+
}
|
|
61288
|
+
}
|
|
61289
|
+
if (keyIdx === -1) return [];
|
|
61290
|
+
const items = [];
|
|
61291
|
+
for (let i = keyIdx + 1; i < lines.length; i++) {
|
|
61292
|
+
const t = lines[i].trimStart();
|
|
61293
|
+
if (t === "" || t.startsWith("#")) continue;
|
|
61294
|
+
if (t === "-" || t.startsWith("- ")) items.push(i);
|
|
61295
|
+
else break;
|
|
61296
|
+
}
|
|
61297
|
+
return items;
|
|
61298
|
+
}
|
|
60898
61299
|
function ompConfigFile() {
|
|
60899
61300
|
const raw = process.env.PI_CODING_AGENT_DIR?.trim();
|
|
60900
|
-
if (raw && raw.length > 0)
|
|
60901
|
-
|
|
61301
|
+
if (raw && raw.length > 0) {
|
|
61302
|
+
if (raw.endsWith("-bili") && raw.length > "-bili".length) {
|
|
61303
|
+
const realHome = raw.slice(0, -"-bili".length);
|
|
61304
|
+
process.stderr.write(
|
|
61305
|
+
`bili plugin: PI_CODING_AGENT_DIR points at the bili overlay ${raw} \u2014 operating on the real omp home ${realHome} instead
|
|
61306
|
+
`
|
|
61307
|
+
);
|
|
61308
|
+
return path13.join(realHome, "config.yml");
|
|
61309
|
+
}
|
|
61310
|
+
return path13.join(raw, "config.yml");
|
|
61311
|
+
}
|
|
61312
|
+
return path13.join(os4.homedir(), ".omp", "agent", "config.yml");
|
|
60902
61313
|
}
|
|
60903
61314
|
function ompExtensionPath() {
|
|
60904
|
-
return
|
|
61315
|
+
return path13.join(selfPackageRoot(), "dist", "agent", "omp.js");
|
|
60905
61316
|
}
|
|
60906
61317
|
function ompEntryValue(line) {
|
|
60907
61318
|
return line.replace(/#.*$/, "").trim().replace(/^-\s*/, "").replace(/^["']|["']$/g, "").trim();
|
|
60908
61319
|
}
|
|
61320
|
+
function ompBlockLoaded(text) {
|
|
61321
|
+
const lines = text.split("\n");
|
|
61322
|
+
return ompExtensionItemLines(text).some((i) => {
|
|
61323
|
+
const v2 = ompEntryValue(lines[i]);
|
|
61324
|
+
return OMP_ENTRY_RE.test(v2) && fs10.existsSync(v2);
|
|
61325
|
+
});
|
|
61326
|
+
}
|
|
60909
61327
|
function ompRemove() {
|
|
60910
61328
|
const file = ompConfigFile();
|
|
60911
|
-
|
|
60912
|
-
|
|
60913
|
-
const
|
|
60914
|
-
const
|
|
60915
|
-
|
|
61329
|
+
if (!fs10.existsSync(file)) return `omp: not installed (${file})`;
|
|
61330
|
+
const text = fs10.readFileSync(file, "utf8");
|
|
61331
|
+
const lines = text.split("\n");
|
|
61332
|
+
const drop = new Set(
|
|
61333
|
+
ompExtensionItemLines(text).filter((i) => OMP_ENTRY_RE.test(ompEntryValue(lines[i])))
|
|
61334
|
+
);
|
|
61335
|
+
if (drop.size === 0) return `omp: not installed (${file})`;
|
|
61336
|
+
const cleaned = lines.filter((_2, i) => !drop.has(i)).join("\n");
|
|
60916
61337
|
backupOnce(file);
|
|
60917
|
-
|
|
61338
|
+
fs10.writeFileSync(file, cleaned);
|
|
60918
61339
|
return `omp: removed from ${file}`;
|
|
60919
61340
|
}
|
|
60920
61341
|
function ompInstall() {
|
|
60921
61342
|
const file = ompConfigFile();
|
|
60922
61343
|
const entry = ompExtensionPath();
|
|
60923
61344
|
requireDistFile(entry);
|
|
60924
|
-
|
|
60925
|
-
|
|
60926
|
-
if (text
|
|
61345
|
+
fs10.mkdirSync(path13.dirname(file), { recursive: true });
|
|
61346
|
+
let text = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
61347
|
+
if (ompBlockLoaded(text)) return `omp: already installed (${file})`;
|
|
61348
|
+
{
|
|
61349
|
+
const lines = text.split("\n");
|
|
61350
|
+
const stale = new Set(ompExtensionItemLines(text).filter((i) => ompEntryValue(lines[i]) === entry));
|
|
61351
|
+
if (stale.size > 0) text = lines.filter((_2, i) => !stale.has(i)).join("\n");
|
|
61352
|
+
}
|
|
60927
61353
|
const keyCount = (text.match(/^extensions:/gm) ?? []).length;
|
|
60928
61354
|
if (keyCount > 1) throw new Error(`${file}: multiple \`extensions:\` keys \u2014 fix the file first, refusing to edit`);
|
|
60929
61355
|
if (/^extensions:\s*\S/m.test(text) && !/^extensions:\s*$/m.test(text)) {
|
|
@@ -60953,26 +61379,31 @@ ${tail}`;
|
|
|
60953
61379
|
- ${entry}
|
|
60954
61380
|
`;
|
|
60955
61381
|
}
|
|
60956
|
-
const
|
|
61382
|
+
const outLines = out.split("\n");
|
|
61383
|
+
const occurrences = ompExtensionItemLines(out).filter((i) => ompEntryValue(outLines[i]) === entry).length;
|
|
60957
61384
|
if (occurrences !== 1) {
|
|
60958
61385
|
throw new Error(`${file}: edit would leave ${occurrences} copies of the entry \u2014 aborting without writing`);
|
|
60959
61386
|
}
|
|
60960
61387
|
backupOnce(file);
|
|
60961
|
-
|
|
61388
|
+
fs10.writeFileSync(file, out);
|
|
60962
61389
|
return `omp: installed -> ${file} extensions += ${entry}`;
|
|
60963
61390
|
}
|
|
60964
61391
|
function ompStatus() {
|
|
60965
61392
|
const file = ompConfigFile();
|
|
60966
|
-
const text =
|
|
60967
|
-
|
|
61393
|
+
const text = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
61394
|
+
const lines = text.split("\n");
|
|
61395
|
+
let broken = false;
|
|
61396
|
+
for (const i of ompExtensionItemLines(text)) {
|
|
61397
|
+
const v2 = ompEntryValue(lines[i]);
|
|
61398
|
+
if (!OMP_ENTRY_RE.test(v2)) continue;
|
|
61399
|
+
if (fs10.existsSync(v2)) return "installed";
|
|
61400
|
+
broken = true;
|
|
61401
|
+
}
|
|
61402
|
+
return broken ? "broken" : "not installed";
|
|
60968
61403
|
}
|
|
60969
61404
|
function ompPluginLoadedFrom(ompHome) {
|
|
60970
61405
|
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
|
-
});
|
|
61406
|
+
return ompBlockLoaded(fs10.readFileSync(path13.join(ompHome, "config.yml"), "utf8"));
|
|
60976
61407
|
} catch {
|
|
60977
61408
|
return false;
|
|
60978
61409
|
}
|
|
@@ -60983,11 +61414,11 @@ function claudeMcpJson() {
|
|
|
60983
61414
|
}
|
|
60984
61415
|
function claudeInstall() {
|
|
60985
61416
|
const root = selfPackageRoot();
|
|
60986
|
-
const mcpJs =
|
|
61417
|
+
const mcpJs = path13.join(root, "dist", "mcp.js");
|
|
60987
61418
|
requireDistFile(mcpJs);
|
|
60988
61419
|
const claude = process.env.CLAUDE?.trim() || "claude";
|
|
60989
61420
|
try {
|
|
60990
|
-
execFileSync2(claude, ["mcp", "add", "bili", "--scope", "user", "-e", `BILI_MCP_PROXY=${
|
|
61421
|
+
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
61422
|
return `claude: installed via \`claude mcp add\` (user scope) -> ${claudeMcpJson()}`;
|
|
60992
61423
|
} catch (err2) {
|
|
60993
61424
|
const stderr = err2 instanceof Error && "stderr" in err2 ? String(err2.stderr ?? "") : "";
|
|
@@ -61010,38 +61441,38 @@ function claudeStatus() {
|
|
|
61010
61441
|
}
|
|
61011
61442
|
function codexToml() {
|
|
61012
61443
|
const raw = process.env.CODEX_HOME?.trim();
|
|
61013
|
-
if (raw && raw.length > 0) return
|
|
61444
|
+
if (raw && raw.length > 0) return path13.join(raw, "config.toml");
|
|
61014
61445
|
return homeFile(".codex/config.toml");
|
|
61015
61446
|
}
|
|
61016
61447
|
function codexBlock() {
|
|
61017
61448
|
return `
|
|
61018
61449
|
[mcp_servers.bili]
|
|
61019
61450
|
command = ${JSON.stringify(process.execPath)}
|
|
61020
|
-
args = [${JSON.stringify(
|
|
61021
|
-
env = { BILI_MCP_PROXY = ${JSON.stringify(
|
|
61451
|
+
args = [${JSON.stringify(path13.join(selfPackageRoot(), "dist", "mcp.js"))}]
|
|
61452
|
+
env = { BILI_MCP_PROXY = ${JSON.stringify(proxyOriginForInstall())} }
|
|
61022
61453
|
`;
|
|
61023
61454
|
}
|
|
61024
61455
|
function codexInstall() {
|
|
61025
61456
|
const file = codexToml();
|
|
61026
|
-
const text =
|
|
61457
|
+
const text = fs10.existsSync(file) ? fs10.readFileSync(file, "utf8") : "";
|
|
61027
61458
|
const existing = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
|
|
61028
61459
|
if (existing !== null) {
|
|
61029
61460
|
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(
|
|
61461
|
+
if (block.includes(`BILI_MCP_PROXY = ${JSON.stringify(proxyOriginForInstall())}`)) return `codex: already installed (${file})`;
|
|
61031
61462
|
const refreshed = text.slice(0, existing.index) + codexBlock().replace(/^\n/, "") + text.slice(existing.index + block.length);
|
|
61032
61463
|
backupOnce(file);
|
|
61033
|
-
|
|
61464
|
+
fs10.writeFileSync(file, refreshed);
|
|
61034
61465
|
return `codex: refreshed proxy origin -> ${file} [mcp_servers.bili]`;
|
|
61035
61466
|
}
|
|
61036
|
-
|
|
61467
|
+
fs10.mkdirSync(path13.dirname(file), { recursive: true });
|
|
61037
61468
|
backupOnce(file);
|
|
61038
|
-
|
|
61469
|
+
fs10.writeFileSync(file, text + (text.endsWith("\n") || text.length === 0 ? "" : "\n") + codexBlock());
|
|
61039
61470
|
return `codex: installed -> ${file} [mcp_servers.bili]`;
|
|
61040
61471
|
}
|
|
61041
61472
|
function codexRemove() {
|
|
61042
61473
|
const file = codexToml();
|
|
61043
|
-
if (!
|
|
61044
|
-
const text =
|
|
61474
|
+
if (!fs10.existsSync(file)) return `codex: not installed (${file})`;
|
|
61475
|
+
const text = fs10.readFileSync(file, "utf8");
|
|
61045
61476
|
const start = (() => {
|
|
61046
61477
|
const m2 = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
|
|
61047
61478
|
return m2 === null ? -1 : m2.index;
|
|
@@ -61054,28 +61485,28 @@ function codexRemove() {
|
|
|
61054
61485
|
const end = nextTable >= 0 ? start + firstNewline + 1 + nextTable : text.length;
|
|
61055
61486
|
const cleaned = (text.slice(0, lineStart).replace(/\n+$/, "\n") + text.slice(end)).replace(/^\n+/, "");
|
|
61056
61487
|
backupOnce(file);
|
|
61057
|
-
|
|
61488
|
+
fs10.writeFileSync(file, cleaned);
|
|
61058
61489
|
return `codex: removed from ${file}`;
|
|
61059
61490
|
}
|
|
61060
61491
|
function codexStatus() {
|
|
61061
|
-
const text =
|
|
61492
|
+
const text = fs10.existsSync(codexToml()) ? fs10.readFileSync(codexToml(), "utf8") : "";
|
|
61062
61493
|
return /^\[mcp_servers\.bili\]\s*$/m.test(text) ? "installed" : "not installed";
|
|
61063
61494
|
}
|
|
61064
61495
|
function opencodeJson() {
|
|
61065
61496
|
const raw = process.env.OPENCODE_CONFIG?.trim();
|
|
61066
61497
|
if (raw && raw.length > 0) return raw;
|
|
61067
61498
|
const xdg2 = process.env.XDG_CONFIG_HOME?.trim();
|
|
61068
|
-
if (xdg2 && xdg2.length > 0) return
|
|
61069
|
-
return
|
|
61499
|
+
if (xdg2 && xdg2.length > 0) return path13.join(xdg2, "opencode/opencode.json");
|
|
61500
|
+
return path13.join(os4.homedir(), ".config", "opencode", "opencode.json");
|
|
61070
61501
|
}
|
|
61071
61502
|
function opencodeInstall() {
|
|
61072
61503
|
const file = opencodeJson();
|
|
61073
|
-
const mcpJs =
|
|
61504
|
+
const mcpJs = path13.join(selfPackageRoot(), "dist", "mcp.js");
|
|
61074
61505
|
requireDistFile(mcpJs);
|
|
61075
61506
|
const data = readJson(file);
|
|
61076
61507
|
const mcp = data.mcp ?? {};
|
|
61077
61508
|
if ("bili" in mcp) return `opencode: already installed (${file})`;
|
|
61078
|
-
mcp.bili = { type: "local", command: [process.execPath, mcpJs], environment: { BILI_MCP_PROXY:
|
|
61509
|
+
mcp.bili = { type: "local", command: [process.execPath, mcpJs], environment: { BILI_MCP_PROXY: proxyOriginForInstall() }, enabled: true };
|
|
61079
61510
|
data.mcp = mcp;
|
|
61080
61511
|
writeJson(file, data);
|
|
61081
61512
|
return `opencode: installed -> ${file} mcp.bili`;
|
|
@@ -61121,15 +61552,15 @@ function pluginStatusAll() {
|
|
|
61121
61552
|
}
|
|
61122
61553
|
|
|
61123
61554
|
// src/launcher.ts
|
|
61124
|
-
import { randomUUID as
|
|
61125
|
-
import
|
|
61555
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
61556
|
+
import fs11 from "fs";
|
|
61126
61557
|
import net2 from "net";
|
|
61127
61558
|
import os5 from "os";
|
|
61128
|
-
import
|
|
61559
|
+
import path14 from "path";
|
|
61129
61560
|
import { pathToFileURL } from "url";
|
|
61130
61561
|
import { spawn } from "child_process";
|
|
61131
61562
|
function selfDistFile(name) {
|
|
61132
|
-
return
|
|
61563
|
+
return path14.join(selfPackageRoot(), "dist", name);
|
|
61133
61564
|
}
|
|
61134
61565
|
var LAUNCHER_DEFAULT_HOST = "127.0.0.1";
|
|
61135
61566
|
var LAUNCHER_DEFAULT_PORT = 8787;
|
|
@@ -61165,12 +61596,12 @@ function unwrapUpstream2(url) {
|
|
|
61165
61596
|
return idx >= 0 ? url.slice(idx + "/bili/".length) : url;
|
|
61166
61597
|
}
|
|
61167
61598
|
function resolveCaCertPath(env) {
|
|
61168
|
-
const base = env.XDG_DATA_HOME ||
|
|
61169
|
-
return
|
|
61599
|
+
const base = env.XDG_DATA_HOME || path14.join(os5.homedir(), ".local/share");
|
|
61600
|
+
return path14.join(base, "billion-context", "ca", "root-ca.pem");
|
|
61170
61601
|
}
|
|
61171
61602
|
function resolveCombinedCaPath(env) {
|
|
61172
|
-
const base = env.XDG_DATA_HOME ||
|
|
61173
|
-
return
|
|
61603
|
+
const base = env.XDG_DATA_HOME || path14.join(os5.homedir(), ".local/share");
|
|
61604
|
+
return path14.join(base, "billion-context", "ca", "combined-ca.pem");
|
|
61174
61605
|
}
|
|
61175
61606
|
function discoverRoutes(client, config) {
|
|
61176
61607
|
const httpsDomains = [];
|
|
@@ -61403,12 +61834,12 @@ function buildCodexMcpArgs(origin, conversationId2) {
|
|
|
61403
61834
|
];
|
|
61404
61835
|
}
|
|
61405
61836
|
function overlayLockPath(overlay) {
|
|
61406
|
-
return
|
|
61837
|
+
return path14.join(overlay, ".bili-launch.pid");
|
|
61407
61838
|
}
|
|
61408
61839
|
function livePidHoldsOverlay(overlay) {
|
|
61409
61840
|
let raw;
|
|
61410
61841
|
try {
|
|
61411
|
-
raw =
|
|
61842
|
+
raw = fs11.readFileSync(overlayLockPath(overlay), "utf8");
|
|
61412
61843
|
} catch {
|
|
61413
61844
|
return void 0;
|
|
61414
61845
|
}
|
|
@@ -61422,10 +61853,10 @@ function livePidHoldsOverlay(overlay) {
|
|
|
61422
61853
|
return pid;
|
|
61423
61854
|
}
|
|
61424
61855
|
function linkOverlayEntry(realHome, overlay, entry) {
|
|
61425
|
-
const target =
|
|
61426
|
-
const link =
|
|
61856
|
+
const target = path14.join(realHome, entry);
|
|
61857
|
+
const link = path14.join(overlay, entry);
|
|
61427
61858
|
try {
|
|
61428
|
-
|
|
61859
|
+
fs11.symlinkSync(target, link);
|
|
61429
61860
|
return true;
|
|
61430
61861
|
} catch (err2) {
|
|
61431
61862
|
const code = err2.code;
|
|
@@ -61433,24 +61864,24 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
61433
61864
|
}
|
|
61434
61865
|
let st2;
|
|
61435
61866
|
try {
|
|
61436
|
-
st2 =
|
|
61867
|
+
st2 = fs11.lstatSync(target);
|
|
61437
61868
|
} catch {
|
|
61438
61869
|
return false;
|
|
61439
61870
|
}
|
|
61440
61871
|
if (st2.isDirectory()) {
|
|
61441
61872
|
try {
|
|
61442
|
-
|
|
61873
|
+
fs11.symlinkSync(target, link, "junction");
|
|
61443
61874
|
return true;
|
|
61444
61875
|
} catch {
|
|
61445
61876
|
return false;
|
|
61446
61877
|
}
|
|
61447
61878
|
}
|
|
61448
61879
|
try {
|
|
61449
|
-
|
|
61880
|
+
fs11.linkSync(target, link);
|
|
61450
61881
|
return true;
|
|
61451
61882
|
} catch {
|
|
61452
61883
|
try {
|
|
61453
|
-
|
|
61884
|
+
fs11.copyFileSync(target, link);
|
|
61454
61885
|
return true;
|
|
61455
61886
|
} catch {
|
|
61456
61887
|
return false;
|
|
@@ -61460,7 +61891,7 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
61460
61891
|
function isWriteThroughHardlink(overlayPath, realPath, st2) {
|
|
61461
61892
|
if (st2.isDirectory() || st2.isSymbolicLink() || st2.nlink <= 1) return false;
|
|
61462
61893
|
try {
|
|
61463
|
-
const realSt =
|
|
61894
|
+
const realSt = fs11.lstatSync(realPath);
|
|
61464
61895
|
return st2.dev === realSt.dev && st2.ino === realSt.ino;
|
|
61465
61896
|
} catch {
|
|
61466
61897
|
return false;
|
|
@@ -61472,7 +61903,7 @@ function sqliteSetMembers(base) {
|
|
|
61472
61903
|
function mergeSqliteSet(overlay, realHome, base) {
|
|
61473
61904
|
const members = sqliteSetMembers(base).filter((m2) => {
|
|
61474
61905
|
try {
|
|
61475
|
-
return
|
|
61906
|
+
return fs11.lstatSync(path14.join(overlay, m2)).isFile();
|
|
61476
61907
|
} catch {
|
|
61477
61908
|
return false;
|
|
61478
61909
|
}
|
|
@@ -61490,44 +61921,44 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
61490
61921
|
};
|
|
61491
61922
|
try {
|
|
61492
61923
|
for (const m2 of members) {
|
|
61493
|
-
const src =
|
|
61494
|
-
const dst =
|
|
61924
|
+
const src = path14.join(overlay, m2);
|
|
61925
|
+
const dst = path14.join(realHome, m2);
|
|
61495
61926
|
let dstStat;
|
|
61496
61927
|
try {
|
|
61497
|
-
dstStat =
|
|
61928
|
+
dstStat = fs11.lstatSync(dst);
|
|
61498
61929
|
} catch {
|
|
61499
61930
|
}
|
|
61500
61931
|
if (dstStat && dstStat.isDirectory()) {
|
|
61501
61932
|
rollback();
|
|
61502
61933
|
return false;
|
|
61503
61934
|
}
|
|
61504
|
-
const srcStat =
|
|
61935
|
+
const srcStat = fs11.lstatSync(src);
|
|
61505
61936
|
if (dstStat && dstStat.mtimeMs >= srcStat.mtimeMs) {
|
|
61506
61937
|
try {
|
|
61507
|
-
|
|
61938
|
+
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
61508
61939
|
} catch {
|
|
61509
61940
|
rollback();
|
|
61510
61941
|
return false;
|
|
61511
61942
|
}
|
|
61512
|
-
undo.push(() =>
|
|
61943
|
+
undo.push(() => fs11.renameSync(`${dst}.bili-conflict`, src));
|
|
61513
61944
|
continue;
|
|
61514
61945
|
}
|
|
61515
61946
|
if (dstStat) {
|
|
61516
61947
|
try {
|
|
61517
|
-
|
|
61948
|
+
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
61518
61949
|
} catch {
|
|
61519
61950
|
rollback();
|
|
61520
61951
|
return false;
|
|
61521
61952
|
}
|
|
61522
|
-
undo.push(() =>
|
|
61953
|
+
undo.push(() => fs11.renameSync(`${dst}.bili-conflict`, dst));
|
|
61523
61954
|
}
|
|
61524
61955
|
try {
|
|
61525
|
-
|
|
61956
|
+
fs11.renameSync(src, dst);
|
|
61526
61957
|
} catch {
|
|
61527
61958
|
rollback();
|
|
61528
61959
|
return false;
|
|
61529
61960
|
}
|
|
61530
|
-
undo.push(() =>
|
|
61961
|
+
undo.push(() => fs11.renameSync(dst, src));
|
|
61531
61962
|
}
|
|
61532
61963
|
return true;
|
|
61533
61964
|
} catch {
|
|
@@ -61537,7 +61968,7 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
61537
61968
|
}
|
|
61538
61969
|
function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
61539
61970
|
try {
|
|
61540
|
-
|
|
61971
|
+
fs11.mkdirSync(overlay, { recursive: true });
|
|
61541
61972
|
} catch {
|
|
61542
61973
|
return false;
|
|
61543
61974
|
}
|
|
@@ -61548,19 +61979,19 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61548
61979
|
);
|
|
61549
61980
|
}
|
|
61550
61981
|
try {
|
|
61551
|
-
|
|
61982
|
+
fs11.writeFileSync(overlayLockPath(overlay), `${process.pid}
|
|
61552
61983
|
`);
|
|
61553
61984
|
} catch {
|
|
61554
61985
|
}
|
|
61555
61986
|
const realEntries = /* @__PURE__ */ new Set();
|
|
61556
61987
|
try {
|
|
61557
|
-
for (const entry of
|
|
61988
|
+
for (const entry of fs11.readdirSync(realHome)) realEntries.add(entry);
|
|
61558
61989
|
} catch {
|
|
61559
61990
|
}
|
|
61560
61991
|
try {
|
|
61561
61992
|
let overlayEntries;
|
|
61562
61993
|
try {
|
|
61563
|
-
overlayEntries =
|
|
61994
|
+
overlayEntries = fs11.readdirSync(overlay);
|
|
61564
61995
|
} catch {
|
|
61565
61996
|
overlayEntries = [];
|
|
61566
61997
|
}
|
|
@@ -61571,10 +62002,10 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61571
62002
|
if (!members.some((m2) => m2 !== entry && overlayEntries.includes(m2))) continue;
|
|
61572
62003
|
let mainSt;
|
|
61573
62004
|
try {
|
|
61574
|
-
mainSt =
|
|
62005
|
+
mainSt = fs11.lstatSync(path14.join(overlay, entry));
|
|
61575
62006
|
} catch {
|
|
61576
62007
|
}
|
|
61577
|
-
const keepSidecars = mainSt !== void 0 && isWriteThroughHardlink(
|
|
62008
|
+
const keepSidecars = mainSt !== void 0 && isWriteThroughHardlink(path14.join(overlay, entry), path14.join(realHome, entry), mainSt);
|
|
61578
62009
|
dbSets.push({ base: entry, keepSidecars });
|
|
61579
62010
|
}
|
|
61580
62011
|
const skipEntries = /* @__PURE__ */ new Set();
|
|
@@ -61585,10 +62016,10 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61585
62016
|
}
|
|
61586
62017
|
for (const entry of overlayEntries) {
|
|
61587
62018
|
if (entry === generatedFile) continue;
|
|
61588
|
-
const overlayPath =
|
|
62019
|
+
const overlayPath = path14.join(overlay, entry);
|
|
61589
62020
|
if (entry.startsWith(`.${generatedFile}.`) && entry.endsWith(".tmp")) {
|
|
61590
62021
|
try {
|
|
61591
|
-
|
|
62022
|
+
fs11.unlinkSync(overlayPath);
|
|
61592
62023
|
} catch {
|
|
61593
62024
|
}
|
|
61594
62025
|
continue;
|
|
@@ -61596,33 +62027,33 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61596
62027
|
if (skipEntries.has(entry)) continue;
|
|
61597
62028
|
let st2;
|
|
61598
62029
|
try {
|
|
61599
|
-
st2 =
|
|
62030
|
+
st2 = fs11.lstatSync(overlayPath);
|
|
61600
62031
|
} catch {
|
|
61601
62032
|
continue;
|
|
61602
62033
|
}
|
|
61603
62034
|
if (st2.isSymbolicLink()) {
|
|
61604
62035
|
let target;
|
|
61605
62036
|
try {
|
|
61606
|
-
target =
|
|
62037
|
+
target = fs11.readlinkSync(overlayPath);
|
|
61607
62038
|
} catch {
|
|
61608
62039
|
}
|
|
61609
|
-
const wanted = realEntries.has(entry) ?
|
|
62040
|
+
const wanted = realEntries.has(entry) ? path14.join(realHome, entry) : void 0;
|
|
61610
62041
|
if (!wanted || target !== wanted) {
|
|
61611
62042
|
try {
|
|
61612
|
-
|
|
62043
|
+
fs11.unlinkSync(overlayPath);
|
|
61613
62044
|
} catch {
|
|
61614
62045
|
}
|
|
61615
62046
|
}
|
|
61616
62047
|
} else if (realEntries.has(entry)) {
|
|
61617
|
-
const realPath =
|
|
62048
|
+
const realPath = path14.join(realHome, entry);
|
|
61618
62049
|
if (isWriteThroughHardlink(overlayPath, realPath, st2)) {
|
|
61619
62050
|
try {
|
|
61620
|
-
|
|
62051
|
+
fs11.unlinkSync(overlayPath);
|
|
61621
62052
|
} catch {
|
|
61622
62053
|
}
|
|
61623
|
-
} else if (mergeOverlayEntry(overlayPath, realPath)) {
|
|
62054
|
+
} else if (mergeOverlayEntry(overlayPath, realPath, generatedFile)) {
|
|
61624
62055
|
try {
|
|
61625
|
-
|
|
62056
|
+
fs11.rmSync(overlayPath, { recursive: true, force: true });
|
|
61626
62057
|
} catch {
|
|
61627
62058
|
}
|
|
61628
62059
|
} else {
|
|
@@ -61644,10 +62075,10 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61644
62075
|
for (const entry of realEntries) {
|
|
61645
62076
|
if (entry === generatedFile) continue;
|
|
61646
62077
|
total += 1;
|
|
61647
|
-
const overlayPath =
|
|
62078
|
+
const overlayPath = path14.join(overlay, entry);
|
|
61648
62079
|
let present = false;
|
|
61649
62080
|
try {
|
|
61650
|
-
|
|
62081
|
+
fs11.lstatSync(overlayPath);
|
|
61651
62082
|
present = true;
|
|
61652
62083
|
} catch {
|
|
61653
62084
|
}
|
|
@@ -61676,47 +62107,48 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
61676
62107
|
}
|
|
61677
62108
|
return true;
|
|
61678
62109
|
}
|
|
61679
|
-
function mergeOverlayEntry(src, dst) {
|
|
62110
|
+
function mergeOverlayEntry(src, dst, excludedName) {
|
|
61680
62111
|
let st2;
|
|
61681
62112
|
try {
|
|
61682
|
-
st2 =
|
|
62113
|
+
st2 = fs11.lstatSync(src);
|
|
61683
62114
|
} catch {
|
|
61684
62115
|
return true;
|
|
61685
62116
|
}
|
|
61686
62117
|
let dstStat;
|
|
61687
62118
|
try {
|
|
61688
|
-
dstStat =
|
|
62119
|
+
dstStat = fs11.lstatSync(dst);
|
|
61689
62120
|
} catch {
|
|
61690
62121
|
}
|
|
61691
62122
|
if (st2.isDirectory()) {
|
|
61692
62123
|
if (dstStat && !dstStat.isDirectory()) {
|
|
61693
62124
|
try {
|
|
61694
|
-
|
|
62125
|
+
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
61695
62126
|
dstStat = void 0;
|
|
61696
62127
|
} catch {
|
|
61697
62128
|
return false;
|
|
61698
62129
|
}
|
|
61699
62130
|
}
|
|
61700
62131
|
try {
|
|
61701
|
-
|
|
62132
|
+
fs11.mkdirSync(dst, { recursive: true });
|
|
61702
62133
|
} catch {
|
|
61703
62134
|
return false;
|
|
61704
62135
|
}
|
|
61705
62136
|
let entries;
|
|
61706
62137
|
try {
|
|
61707
|
-
entries =
|
|
62138
|
+
entries = fs11.readdirSync(src);
|
|
61708
62139
|
} catch {
|
|
61709
62140
|
return false;
|
|
61710
62141
|
}
|
|
61711
62142
|
let ok = true;
|
|
61712
62143
|
for (const entry of entries) {
|
|
61713
|
-
if (
|
|
62144
|
+
if (excludedName !== void 0 && entry === excludedName) continue;
|
|
62145
|
+
if (!mergeOverlayEntry(path14.join(src, entry), path14.join(dst, entry), excludedName)) ok = false;
|
|
61714
62146
|
}
|
|
61715
62147
|
return ok;
|
|
61716
62148
|
}
|
|
61717
62149
|
if (dstStat && dstStat.isDirectory()) {
|
|
61718
62150
|
try {
|
|
61719
|
-
|
|
62151
|
+
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
61720
62152
|
return true;
|
|
61721
62153
|
} catch {
|
|
61722
62154
|
return false;
|
|
@@ -61725,13 +62157,13 @@ function mergeOverlayEntry(src, dst) {
|
|
|
61725
62157
|
if (st2.isSymbolicLink()) {
|
|
61726
62158
|
if (dstStat) {
|
|
61727
62159
|
try {
|
|
61728
|
-
|
|
62160
|
+
fs11.unlinkSync(src);
|
|
61729
62161
|
} catch {
|
|
61730
62162
|
}
|
|
61731
62163
|
return true;
|
|
61732
62164
|
}
|
|
61733
62165
|
try {
|
|
61734
|
-
|
|
62166
|
+
fs11.renameSync(src, dst);
|
|
61735
62167
|
} catch {
|
|
61736
62168
|
return false;
|
|
61737
62169
|
}
|
|
@@ -61739,7 +62171,7 @@ function mergeOverlayEntry(src, dst) {
|
|
|
61739
62171
|
}
|
|
61740
62172
|
if (dstStat && dstStat.mtimeMs >= st2.mtimeMs) {
|
|
61741
62173
|
try {
|
|
61742
|
-
|
|
62174
|
+
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
61743
62175
|
return true;
|
|
61744
62176
|
} catch {
|
|
61745
62177
|
return false;
|
|
@@ -61747,13 +62179,13 @@ function mergeOverlayEntry(src, dst) {
|
|
|
61747
62179
|
}
|
|
61748
62180
|
if (dstStat) {
|
|
61749
62181
|
try {
|
|
61750
|
-
|
|
62182
|
+
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
61751
62183
|
} catch {
|
|
61752
62184
|
return false;
|
|
61753
62185
|
}
|
|
61754
62186
|
}
|
|
61755
62187
|
try {
|
|
61756
|
-
|
|
62188
|
+
fs11.renameSync(src, dst);
|
|
61757
62189
|
return true;
|
|
61758
62190
|
} catch {
|
|
61759
62191
|
return false;
|
|
@@ -61763,7 +62195,7 @@ function piPluginInstalled(piHome) {
|
|
|
61763
62195
|
const root = selfPackageRoot();
|
|
61764
62196
|
if (!root) return false;
|
|
61765
62197
|
try {
|
|
61766
|
-
const parsed = JSON.parse(
|
|
62198
|
+
const parsed = JSON.parse(fs11.readFileSync(path14.join(piHome, "settings.json"), "utf8"));
|
|
61767
62199
|
const list = Array.isArray(parsed.packages) ? parsed.packages.map(String) : [];
|
|
61768
62200
|
return list.some((p2) => isBiliPiEntry(p2, root));
|
|
61769
62201
|
} catch {
|
|
@@ -61771,23 +62203,23 @@ function piPluginInstalled(piHome) {
|
|
|
61771
62203
|
}
|
|
61772
62204
|
}
|
|
61773
62205
|
function writeOverlayFileAtomic(overlay, fileName, contents) {
|
|
61774
|
-
const draft =
|
|
62206
|
+
const draft = path14.join(overlay, `.${fileName}.${process.pid}.tmp`);
|
|
61775
62207
|
try {
|
|
61776
|
-
|
|
61777
|
-
|
|
62208
|
+
fs11.writeFileSync(draft, contents);
|
|
62209
|
+
fs11.renameSync(draft, path14.join(overlay, fileName));
|
|
61778
62210
|
} catch {
|
|
61779
62211
|
try {
|
|
61780
|
-
|
|
62212
|
+
fs11.rmSync(draft, { force: true });
|
|
61781
62213
|
} catch {
|
|
61782
62214
|
}
|
|
61783
62215
|
}
|
|
61784
62216
|
}
|
|
61785
62217
|
function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
61786
62218
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
|
|
61787
|
-
const modelsPath =
|
|
62219
|
+
const modelsPath = path14.join(piHome, "models.json");
|
|
61788
62220
|
let txt;
|
|
61789
62221
|
try {
|
|
61790
|
-
txt =
|
|
62222
|
+
txt = fs11.readFileSync(modelsPath, "utf8");
|
|
61791
62223
|
} catch {
|
|
61792
62224
|
return void 0;
|
|
61793
62225
|
}
|
|
@@ -61823,12 +62255,64 @@ function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
|
61823
62255
|
writeOverlayFileAtomic(overlay, "models.json", JSON.stringify(root));
|
|
61824
62256
|
return overlay;
|
|
61825
62257
|
}
|
|
62258
|
+
function atomicWriteTextFile(filePath, contents) {
|
|
62259
|
+
const draft = `${filePath}.${process.pid}.bili-tmp`;
|
|
62260
|
+
try {
|
|
62261
|
+
fs11.writeFileSync(draft, contents);
|
|
62262
|
+
fs11.renameSync(draft, filePath);
|
|
62263
|
+
} catch {
|
|
62264
|
+
try {
|
|
62265
|
+
fs11.rmSync(draft, { force: true });
|
|
62266
|
+
} catch {
|
|
62267
|
+
}
|
|
62268
|
+
throw new Error(`bili: could not write ${filePath}`);
|
|
62269
|
+
}
|
|
62270
|
+
}
|
|
62271
|
+
function liveProxyPorts() {
|
|
62272
|
+
const ports = /* @__PURE__ */ new Set();
|
|
62273
|
+
const inst = readProxyInstanceFile();
|
|
62274
|
+
if (isProxyInstanceFile(inst)) {
|
|
62275
|
+
if (isPidAlive(inst.pid)) ports.add(inst.port);
|
|
62276
|
+
} else if (inst) {
|
|
62277
|
+
try {
|
|
62278
|
+
ports.add(new URL(inst.origin).port === "" ? 80 : Number(new URL(inst.origin).port));
|
|
62279
|
+
} catch {
|
|
62280
|
+
}
|
|
62281
|
+
}
|
|
62282
|
+
return ports;
|
|
62283
|
+
}
|
|
62284
|
+
function unpackDeadProxyUrlsInFile(filePath, livePorts) {
|
|
62285
|
+
let txt;
|
|
62286
|
+
try {
|
|
62287
|
+
txt = fs11.readFileSync(filePath, "utf8");
|
|
62288
|
+
} catch {
|
|
62289
|
+
return 0;
|
|
62290
|
+
}
|
|
62291
|
+
const re2 = /https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):(\d+)\/bili\/(https?:\/\/\S+)/g;
|
|
62292
|
+
let changed = 0;
|
|
62293
|
+
const out = txt.replace(re2, (full, portStr, raw) => {
|
|
62294
|
+
if (livePorts.has(Number(portStr))) return full;
|
|
62295
|
+
changed += 1;
|
|
62296
|
+
return raw;
|
|
62297
|
+
});
|
|
62298
|
+
if (changed === 0) return 0;
|
|
62299
|
+
try {
|
|
62300
|
+
atomicWriteTextFile(filePath, out);
|
|
62301
|
+
} catch {
|
|
62302
|
+
return 0;
|
|
62303
|
+
}
|
|
62304
|
+
return changed;
|
|
62305
|
+
}
|
|
61826
62306
|
function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
|
|
62307
|
+
const modelsPath = path14.join(ompHome, "models.yml");
|
|
62308
|
+
const unpacked = unpackDeadProxyUrlsInFile(modelsPath, liveProxyPorts());
|
|
62309
|
+
if (unpacked > 0) {
|
|
62310
|
+
console.error(`bili: unpacked ${unpacked} dead proxy URL(s) from the real ${modelsPath}`);
|
|
62311
|
+
}
|
|
61827
62312
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
|
|
61828
|
-
const modelsPath = path13.join(ompHome, "models.yml");
|
|
61829
62313
|
let txt;
|
|
61830
62314
|
try {
|
|
61831
|
-
txt =
|
|
62315
|
+
txt = fs11.readFileSync(modelsPath, "utf8");
|
|
61832
62316
|
} catch {
|
|
61833
62317
|
return void 0;
|
|
61834
62318
|
}
|
|
@@ -61872,10 +62356,10 @@ function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
|
|
|
61872
62356
|
}
|
|
61873
62357
|
function prepareHermesHome(hermesHome, origin, rewrites) {
|
|
61874
62358
|
if (rewrites.length === 0) return void 0;
|
|
61875
|
-
const cfgPath =
|
|
62359
|
+
const cfgPath = path14.join(hermesHome, "config.yaml");
|
|
61876
62360
|
let txt;
|
|
61877
62361
|
try {
|
|
61878
|
-
txt =
|
|
62362
|
+
txt = fs11.readFileSync(cfgPath, "utf8");
|
|
61879
62363
|
} catch {
|
|
61880
62364
|
return void 0;
|
|
61881
62365
|
}
|
|
@@ -61902,21 +62386,21 @@ function prepareHermesHome(hermesHome, origin, rewrites) {
|
|
|
61902
62386
|
}
|
|
61903
62387
|
function writeHermesIdentityPlugin(hermesHome, overlay, rewrites) {
|
|
61904
62388
|
try {
|
|
61905
|
-
if (
|
|
62389
|
+
if (fs11.existsSync(path14.join(hermesHome, "plugins"))) return false;
|
|
61906
62390
|
} catch {
|
|
61907
62391
|
return false;
|
|
61908
62392
|
}
|
|
61909
|
-
const dir =
|
|
62393
|
+
const dir = path14.join("plugins", "model-providers", "bili-session-identity");
|
|
61910
62394
|
try {
|
|
61911
|
-
|
|
62395
|
+
fs11.mkdirSync(path14.join(overlay, dir), { recursive: true });
|
|
61912
62396
|
} catch {
|
|
61913
62397
|
return false;
|
|
61914
62398
|
}
|
|
61915
62399
|
const keys = rewrites.map((r) => r.key);
|
|
61916
|
-
const pluginDir =
|
|
62400
|
+
const pluginDir = path14.join(overlay, dir);
|
|
61917
62401
|
try {
|
|
61918
|
-
|
|
61919
|
-
|
|
62402
|
+
fs11.writeFileSync(path14.join(pluginDir, "__init__.py"), hermesIdentityPluginSource(keys));
|
|
62403
|
+
fs11.writeFileSync(path14.join(pluginDir, "plugin.yaml"), [
|
|
61920
62404
|
"name: bili-session-identity",
|
|
61921
62405
|
"kind: model-provider",
|
|
61922
62406
|
"version: 1.0.0",
|
|
@@ -61928,7 +62412,7 @@ function writeHermesIdentityPlugin(hermesHome, overlay, rewrites) {
|
|
|
61928
62412
|
return false;
|
|
61929
62413
|
}
|
|
61930
62414
|
try {
|
|
61931
|
-
return
|
|
62415
|
+
return fs11.existsSync(path14.join(overlay, dir, "__init__.py"));
|
|
61932
62416
|
} catch {
|
|
61933
62417
|
return false;
|
|
61934
62418
|
}
|
|
@@ -61985,10 +62469,10 @@ function hermesIdentityPluginSource(providerKeys) {
|
|
|
61985
62469
|
].join("\n");
|
|
61986
62470
|
}
|
|
61987
62471
|
function prepareDshHome(dshHome, origin, rewrites) {
|
|
61988
|
-
const cfgPath =
|
|
62472
|
+
const cfgPath = path14.join(dshHome, "settings.yaml");
|
|
61989
62473
|
let txt;
|
|
61990
62474
|
try {
|
|
61991
|
-
txt =
|
|
62475
|
+
txt = fs11.readFileSync(cfgPath, "utf8");
|
|
61992
62476
|
} catch {
|
|
61993
62477
|
return void 0;
|
|
61994
62478
|
}
|
|
@@ -62016,16 +62500,16 @@ function writeDshAcpPatch(dshHome) {
|
|
|
62016
62500
|
const pluginUrl = pathToFileURL(selfDistFile("agent/dsh-acp.js")).href;
|
|
62017
62501
|
const dir = `${dshHome}-bili`;
|
|
62018
62502
|
try {
|
|
62019
|
-
|
|
62503
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
62020
62504
|
} catch {
|
|
62021
62505
|
return void 0;
|
|
62022
62506
|
}
|
|
62023
62507
|
writeOverlayFileAtomic(dir, ".bili-acp.patch.yml", `- insert:
|
|
62024
62508
|
- name: ${pluginUrl}
|
|
62025
62509
|
`);
|
|
62026
|
-
const file =
|
|
62510
|
+
const file = path14.join(dir, ".bili-acp.patch.yml");
|
|
62027
62511
|
try {
|
|
62028
|
-
return
|
|
62512
|
+
return fs11.existsSync(file) ? file : void 0;
|
|
62029
62513
|
} catch {
|
|
62030
62514
|
return void 0;
|
|
62031
62515
|
}
|
|
@@ -62040,7 +62524,7 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
|
|
|
62040
62524
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0 && !pluginPath) return void 0;
|
|
62041
62525
|
let root = {};
|
|
62042
62526
|
try {
|
|
62043
|
-
const txt =
|
|
62527
|
+
const txt = fs11.readFileSync(configFile2, "utf8");
|
|
62044
62528
|
const parsed = JSON.parse(txt);
|
|
62045
62529
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
62046
62530
|
root = { ...parsed };
|
|
@@ -62068,9 +62552,9 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
|
|
|
62068
62552
|
if (!plugins.includes(pluginPath)) plugins.push(pluginPath);
|
|
62069
62553
|
root.plugin = plugins;
|
|
62070
62554
|
}
|
|
62071
|
-
const tmp =
|
|
62072
|
-
const tmpFile =
|
|
62073
|
-
|
|
62555
|
+
const tmp = fs11.mkdtempSync(path14.join(os5.tmpdir(), "bili-opencode-"));
|
|
62556
|
+
const tmpFile = path14.join(tmp, "opencode.json");
|
|
62557
|
+
fs11.writeFileSync(tmpFile, JSON.stringify(root));
|
|
62074
62558
|
return tmpFile;
|
|
62075
62559
|
}
|
|
62076
62560
|
function dedupeInOrder(list) {
|
|
@@ -62104,27 +62588,33 @@ async function probeHealth(origin, fetchImpl) {
|
|
|
62104
62588
|
return false;
|
|
62105
62589
|
}
|
|
62106
62590
|
}
|
|
62107
|
-
function
|
|
62108
|
-
|
|
62109
|
-
const
|
|
62110
|
-
|
|
62111
|
-
|
|
62112
|
-
|
|
62113
|
-
}
|
|
62114
|
-
|
|
62115
|
-
|
|
62116
|
-
|
|
62117
|
-
|
|
62118
|
-
|
|
62119
|
-
|
|
62120
|
-
|
|
62121
|
-
|
|
62122
|
-
|
|
62123
|
-
|
|
62124
|
-
|
|
62125
|
-
|
|
62126
|
-
|
|
62127
|
-
|
|
62591
|
+
async function fetchHealthInfoDefault(origin) {
|
|
62592
|
+
try {
|
|
62593
|
+
const res = await fetch(healthUrl(origin), { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
|
|
62594
|
+
if (!res.ok) return void 0;
|
|
62595
|
+
const data = await res.json();
|
|
62596
|
+
return { ok: Boolean(data.ok), instanceId: typeof data.instanceId === "string" ? data.instanceId : void 0 };
|
|
62597
|
+
} catch {
|
|
62598
|
+
return void 0;
|
|
62599
|
+
}
|
|
62600
|
+
}
|
|
62601
|
+
function instanceCompatible(inst, opts) {
|
|
62602
|
+
if (inst.host !== opts.host || inst.passthrough !== opts.passthrough) return false;
|
|
62603
|
+
const wantDomains = opts.mitmDomains ?? [];
|
|
62604
|
+
if (inst.mitmDomains.length !== wantDomains.length || inst.mitmDomains.some((d, i) => d !== wantDomains[i])) return false;
|
|
62605
|
+
const wantWindows = opts.modelWindows ?? {};
|
|
62606
|
+
const keys = Object.keys(wantWindows);
|
|
62607
|
+
if (Object.keys(inst.modelWindows).length !== keys.length) return false;
|
|
62608
|
+
return keys.every((k2) => inst.modelWindows[k2] === wantWindows[k2]);
|
|
62609
|
+
}
|
|
62610
|
+
async function probeExistingInstance(readInstance, fetchHealthInfo) {
|
|
62611
|
+
const inst = readInstance();
|
|
62612
|
+
if (!isProxyInstanceFile(inst)) return void 0;
|
|
62613
|
+
if (!isPidAlive(inst.pid)) return void 0;
|
|
62614
|
+
const health = await fetchHealthInfo(inst.origin);
|
|
62615
|
+
if (!health || !health.ok) return void 0;
|
|
62616
|
+
if (health.instanceId !== void 0 && health.instanceId !== inst.instanceId) return void 0;
|
|
62617
|
+
return inst;
|
|
62128
62618
|
}
|
|
62129
62619
|
var INHERITED_PROXY_VARS = ["http_proxy", "https_proxy", "all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY"];
|
|
62130
62620
|
function stripInheritedProxy(env) {
|
|
@@ -62140,25 +62630,34 @@ function proxyStartArgs(opts) {
|
|
|
62140
62630
|
}
|
|
62141
62631
|
async function ensureProxyRunning(opts, deps = {}) {
|
|
62142
62632
|
const fetchImpl = deps.fetchImpl ?? defaultFetch;
|
|
62633
|
+
const fetchHealthInfo = deps.fetchHealthInfo ?? fetchHealthInfoDefault;
|
|
62634
|
+
const readInstance = deps.readInstanceFile ?? readProxyInstanceFile;
|
|
62143
62635
|
const spawnImpl = deps.spawnImpl ?? spawn;
|
|
62144
62636
|
const now = deps.now ?? Date.now;
|
|
62145
62637
|
const sleepImpl = deps.sleep ?? ((ms2) => new Promise((r) => setTimeout(r, ms2)));
|
|
62146
|
-
const
|
|
62147
|
-
|
|
62638
|
+
const existing = await probeExistingInstance(readInstance, fetchHealthInfo);
|
|
62639
|
+
if (existing && instanceCompatible(existing, opts)) {
|
|
62640
|
+
console.error(`bili: attaching to running proxy at ${existing.origin} (pid ${existing.pid})`);
|
|
62641
|
+
return { origin: existing.origin, port: existing.port, attached: true };
|
|
62642
|
+
}
|
|
62643
|
+
const launchToken = randomUUID5();
|
|
62644
|
+
const port = opts.port;
|
|
62148
62645
|
const script = process.argv[1];
|
|
62149
62646
|
if (!script) throw new Error("bili: cannot resolve launcher script path");
|
|
62150
|
-
const logPath2 =
|
|
62151
|
-
const logFd =
|
|
62647
|
+
const logPath2 = path14.join(os5.tmpdir(), `bili-proxy-${port}.log`);
|
|
62648
|
+
const logFd = fs11.openSync(logPath2, "a");
|
|
62152
62649
|
let child;
|
|
62153
62650
|
try {
|
|
62154
62651
|
child = spawnImpl(
|
|
62155
62652
|
process.execPath,
|
|
62156
|
-
[script, ...proxyStartArgs(
|
|
62653
|
+
[script, ...proxyStartArgs(opts)],
|
|
62157
62654
|
{
|
|
62158
62655
|
detached: true,
|
|
62159
62656
|
stdio: ["ignore", logFd, logFd],
|
|
62160
62657
|
env: {
|
|
62161
62658
|
...stripInheritedProxy(process.env),
|
|
62659
|
+
BILI_LAUNCH_TOKEN: launchToken,
|
|
62660
|
+
BILI_PARENT_PID: String(process.pid),
|
|
62162
62661
|
...opts.mitmDomains && opts.mitmDomains.length ? { BILI_MITM_DOMAINS: opts.mitmDomains.join(",") } : {},
|
|
62163
62662
|
...opts.modelWindows && Object.keys(opts.modelWindows).length > 0 ? { BILI_LAUNCHER_MODEL_WINDOWS: JSON.stringify(opts.modelWindows) } : {}
|
|
62164
62663
|
}
|
|
@@ -62166,7 +62665,7 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
62166
62665
|
);
|
|
62167
62666
|
} finally {
|
|
62168
62667
|
try {
|
|
62169
|
-
|
|
62668
|
+
fs11.closeSync(logFd);
|
|
62170
62669
|
} catch {
|
|
62171
62670
|
}
|
|
62172
62671
|
}
|
|
@@ -62177,16 +62676,28 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
62177
62676
|
const deadline = now() + SPAWN_WAIT_MS;
|
|
62178
62677
|
while (now() < deadline) {
|
|
62179
62678
|
await sleepImpl(HEALTH_POLL_INTERVAL_MS);
|
|
62180
|
-
|
|
62181
|
-
|
|
62679
|
+
const inst = readInstance();
|
|
62680
|
+
if (isProxyInstanceFile(inst) && inst.launchToken === launchToken) {
|
|
62681
|
+
if (await probeHealth(inst.origin, fetchImpl)) {
|
|
62682
|
+
return { origin: inst.origin, port: inst.port, child, logPath: logPath2 };
|
|
62683
|
+
}
|
|
62684
|
+
continue;
|
|
62685
|
+
}
|
|
62686
|
+
const stale = !isProxyInstanceFile(inst) || !isPidAlive(inst.pid);
|
|
62687
|
+
if (stale && await probeHealth(proxyOrigin(opts.host, port), fetchImpl)) {
|
|
62688
|
+
return { origin: proxyOrigin(opts.host, port), port, child, logPath: logPath2 };
|
|
62182
62689
|
}
|
|
62183
62690
|
}
|
|
62184
|
-
throw new Error(`bili: proxy did not become healthy
|
|
62691
|
+
throw new Error(`bili: proxy did not become healthy within ${SPAWN_WAIT_MS}ms (log: ${logPath2})`);
|
|
62185
62692
|
}
|
|
62186
62693
|
function stopProxy(handle2) {
|
|
62694
|
+
if (handle2.attached) return;
|
|
62187
62695
|
const child = handle2.child;
|
|
62188
62696
|
if (!child || child.pid === void 0) return;
|
|
62189
|
-
if (process.platform
|
|
62697
|
+
if (process.platform === "win32") {
|
|
62698
|
+
return;
|
|
62699
|
+
}
|
|
62700
|
+
if (child.pid > 0) {
|
|
62190
62701
|
try {
|
|
62191
62702
|
process.kill(-child.pid);
|
|
62192
62703
|
} catch {
|
|
@@ -62213,12 +62724,12 @@ var PATH_EXTS = process.platform === "win32" ? [".cmd", ".bat", ".exe", ""] : ["
|
|
|
62213
62724
|
function resolveOnPath(name, env) {
|
|
62214
62725
|
const p2 = env.PATH;
|
|
62215
62726
|
if (!p2) return void 0;
|
|
62216
|
-
for (const dir of p2.split(
|
|
62727
|
+
for (const dir of p2.split(path14.delimiter)) {
|
|
62217
62728
|
if (!dir) continue;
|
|
62218
62729
|
for (const ext of PATH_EXTS) {
|
|
62219
|
-
const f2 =
|
|
62730
|
+
const f2 = path14.join(dir, name + ext);
|
|
62220
62731
|
try {
|
|
62221
|
-
if (
|
|
62732
|
+
if (fs11.existsSync(f2) && fs11.statSync(f2).isFile()) return f2;
|
|
62222
62733
|
} catch {
|
|
62223
62734
|
}
|
|
62224
62735
|
}
|
|
@@ -62236,7 +62747,7 @@ function resolveClientCommand(client, env) {
|
|
|
62236
62747
|
if (piBin) return { command: piBin, prefixArgs: [] };
|
|
62237
62748
|
const piResolved = resolveOnPath("pi", env);
|
|
62238
62749
|
if (piResolved) return { command: piResolved, prefixArgs: [] };
|
|
62239
|
-
const cli =
|
|
62750
|
+
const cli = path14.join(
|
|
62240
62751
|
os5.homedir(),
|
|
62241
62752
|
".pi/agent/npm/node_modules/@earendil-works/pi-coding-agent/dist/cli.js"
|
|
62242
62753
|
);
|
|
@@ -62308,7 +62819,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
62308
62819
|
piOverlayHome = preparePiHttpRewrite(resolvePiHome(process.env), origin, routes.httpRewrites, routes.httpsRewrites);
|
|
62309
62820
|
if (piOverlayHome) env.PI_CODING_AGENT_DIR = piOverlayHome;
|
|
62310
62821
|
const piExt = selfDistFile("agent/pi.js");
|
|
62311
|
-
if (piExt &&
|
|
62822
|
+
if (piExt && fs11.existsSync(piExt) && !piPluginInstalled(resolvePiHome(process.env))) {
|
|
62312
62823
|
clientArgs = ["-e", piExt, ...clientArgs];
|
|
62313
62824
|
}
|
|
62314
62825
|
} else if (base === "omp") {
|
|
@@ -62316,13 +62827,13 @@ async function runLaunch(params, deps = {}) {
|
|
|
62316
62827
|
ompOverlayHome = prepareOmpHttpRewrite(resolveOmpHome(process.env), origin, routes.httpRewrites, routes.httpsRewrites);
|
|
62317
62828
|
if (ompOverlayHome) env.PI_CODING_AGENT_DIR = ompOverlayHome;
|
|
62318
62829
|
const ompExt = selfDistFile("agent/omp.js");
|
|
62319
|
-
if (ompExt &&
|
|
62830
|
+
if (ompExt && fs11.existsSync(ompExt) && !ompPluginLoadedFrom(resolveOmpHome(process.env))) {
|
|
62320
62831
|
clientArgs = ["-e", ompExt, ...clientArgs];
|
|
62321
62832
|
}
|
|
62322
62833
|
} else if (base === "opencode") {
|
|
62323
62834
|
env = { ...process.env, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: ca, BILLION_CONTEXT_PROXY: origin };
|
|
62324
62835
|
const opencodePlugin = selfDistFile("agent/opencode.js");
|
|
62325
|
-
const opencodePluginPath = opencodePlugin &&
|
|
62836
|
+
const opencodePluginPath = opencodePlugin && fs11.existsSync(opencodePlugin) ? opencodePlugin : void 0;
|
|
62326
62837
|
opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
|
|
62327
62838
|
if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
|
|
62328
62839
|
} else if (base === "hermes") {
|
|
@@ -62360,7 +62871,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
62360
62871
|
const dshAcpPatch = writeDshAcpPatch(dshHomeDir);
|
|
62361
62872
|
if (dshAcpPatch) clientArgs = dshArgsWithPatch(clientArgs, dshAcpPatch);
|
|
62362
62873
|
} else if (base === "codex") {
|
|
62363
|
-
const codexConversationId = injectMcp ?
|
|
62874
|
+
const codexConversationId = injectMcp ? randomUUID5() : void 0;
|
|
62364
62875
|
if (directUrl) {
|
|
62365
62876
|
env = { ...process.env, BILLION_CONTEXT_PROXY: origin };
|
|
62366
62877
|
if (codexConversationId) clientArgs = [...buildCodexMcpArgs(origin, codexConversationId), ...clientArgs];
|
|
@@ -62395,8 +62906,8 @@ async function runLaunch(params, deps = {}) {
|
|
|
62395
62906
|
console.error(`bili: claude budget aligned \u2014 CLAUDE_CODE_AUTO_COMPACT_WINDOW=${claudeBudget.CLAUDE_CODE_AUTO_COMPACT_WINDOW}`);
|
|
62396
62907
|
}
|
|
62397
62908
|
if (injectMcp) {
|
|
62398
|
-
const mcpFile =
|
|
62399
|
-
|
|
62909
|
+
const mcpFile = path14.join(os5.tmpdir(), `bili-mcp-${Date.now()}.json`);
|
|
62910
|
+
fs11.writeFileSync(mcpFile, JSON.stringify(buildMcpConfig(origin)));
|
|
62400
62911
|
tmpFiles.push(mcpFile);
|
|
62401
62912
|
clientArgs = ["--mcp-config", mcpFile, ...clientArgs];
|
|
62402
62913
|
}
|
|
@@ -62415,13 +62926,13 @@ async function runLaunch(params, deps = {}) {
|
|
|
62415
62926
|
stopProxy(handle2);
|
|
62416
62927
|
if (opencodeTmpFile) {
|
|
62417
62928
|
try {
|
|
62418
|
-
|
|
62929
|
+
fs11.rmSync(path14.dirname(opencodeTmpFile), { recursive: true, force: true });
|
|
62419
62930
|
} catch {
|
|
62420
62931
|
}
|
|
62421
62932
|
}
|
|
62422
62933
|
for (const f2 of tmpFiles) {
|
|
62423
62934
|
try {
|
|
62424
|
-
|
|
62935
|
+
fs11.rmSync(f2, { force: true });
|
|
62425
62936
|
} catch {
|
|
62426
62937
|
}
|
|
62427
62938
|
}
|
|
@@ -62447,8 +62958,8 @@ async function runTestPi(params, deps = {}) {
|
|
|
62447
62958
|
}
|
|
62448
62959
|
const ca = resolveCaCertPath(process.env);
|
|
62449
62960
|
const env = buildPiEnv(handle2.origin, ca, process.env);
|
|
62450
|
-
const sessionDir =
|
|
62451
|
-
|
|
62961
|
+
const sessionDir = path14.join(os5.tmpdir(), `bili-pi-test-${Date.now()}`);
|
|
62962
|
+
fs11.mkdirSync(sessionDir, { recursive: true });
|
|
62452
62963
|
const args = [
|
|
62453
62964
|
"-p",
|
|
62454
62965
|
"--no-session",
|
|
@@ -62476,7 +62987,7 @@ async function runTestPi(params, deps = {}) {
|
|
|
62476
62987
|
|
|
62477
62988
|
// src/export.ts
|
|
62478
62989
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
62479
|
-
import
|
|
62990
|
+
import path15 from "path";
|
|
62480
62991
|
function fmtDate(ms2) {
|
|
62481
62992
|
return ms2 ? new Date(ms2).toISOString().replace("T", " ").slice(0, 19) + " UTC" : "\u2014";
|
|
62482
62993
|
}
|
|
@@ -62608,7 +63119,7 @@ async function exportSession(selector, opts = {}) {
|
|
|
62608
63119
|
}
|
|
62609
63120
|
const markdown = renderHandoff(matches[0], opts.full ?? false);
|
|
62610
63121
|
if (opts.output) {
|
|
62611
|
-
mkdirSync5(
|
|
63122
|
+
mkdirSync5(path15.dirname(path15.resolve(opts.output)), { recursive: true });
|
|
62612
63123
|
writeFileSync4(opts.output, markdown, "utf8");
|
|
62613
63124
|
return `written to ${opts.output}`;
|
|
62614
63125
|
}
|
|
@@ -62618,11 +63129,11 @@ async function exportSession(selector, opts = {}) {
|
|
|
62618
63129
|
// src/cli.ts
|
|
62619
63130
|
import { readFileSync as readFileSync4 } from "fs";
|
|
62620
63131
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
62621
|
-
import
|
|
63132
|
+
import path16 from "path";
|
|
62622
63133
|
var VERSION3 = (() => {
|
|
62623
63134
|
try {
|
|
62624
63135
|
const here = fileURLToPath6(import.meta.url);
|
|
62625
|
-
const pkg =
|
|
63136
|
+
const pkg = path16.join(path16.dirname(here), "..", "package.json");
|
|
62626
63137
|
return JSON.parse(readFileSync4(pkg, "utf8")).version ?? "dev";
|
|
62627
63138
|
} catch {
|
|
62628
63139
|
return "dev";
|
|
@@ -62631,7 +63142,7 @@ var VERSION3 = (() => {
|
|
|
62631
63142
|
var PACKAGE_NAME = (() => {
|
|
62632
63143
|
try {
|
|
62633
63144
|
const here = fileURLToPath6(import.meta.url);
|
|
62634
|
-
const pkg =
|
|
63145
|
+
const pkg = path16.join(path16.dirname(here), "..", "package.json");
|
|
62635
63146
|
return JSON.parse(readFileSync4(pkg, "utf8")).name ?? "billion-context";
|
|
62636
63147
|
} catch {
|
|
62637
63148
|
return "billion-context";
|