billion-context 0.1.67 → 0.1.68-pr.428.255

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