billion-context 0.1.110 → 0.1.111-pr.748.622

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
@@ -49414,7 +49414,7 @@ function rejectLegacyRoute(key, value) {
49414
49414
 
49415
49415
  // src/server.ts
49416
49416
  import http from "http";
49417
- import fs8 from "fs";
49417
+ import fs9 from "fs";
49418
49418
  import { randomUUID as randomUUID4 } from "crypto";
49419
49419
 
49420
49420
  // src/compress-settings.ts
@@ -54348,6 +54348,66 @@ ${icon} [ACP] ${inner}
54348
54348
  `;
54349
54349
  }
54350
54350
 
54351
+ // src/tool-pair-order.ts
54352
+ var CALL_TYPES = /* @__PURE__ */ new Set(["function_call", "custom_tool_call"]);
54353
+ var OUTPUT_TYPES = /* @__PURE__ */ new Set(["function_call_output", "custom_tool_call_output"]);
54354
+ function isCall(type) {
54355
+ return type !== void 0 && CALL_TYPES.has(type);
54356
+ }
54357
+ function isOutput(type) {
54358
+ return type !== void 0 && OUTPUT_TYPES.has(type);
54359
+ }
54360
+ function idOf(item) {
54361
+ return typeof item.call_id === "string" ? item.call_id : "";
54362
+ }
54363
+ function hoistTrappedToolItems(items) {
54364
+ const n = items.length;
54365
+ if (n < 3) return items;
54366
+ const callPos = /* @__PURE__ */ new Map();
54367
+ const outPos = /* @__PURE__ */ new Map();
54368
+ for (let i = 0; i < n; i++) {
54369
+ const id = idOf(items[i]);
54370
+ if (!id) continue;
54371
+ const t = items[i].type;
54372
+ if (isCall(t) && !callPos.has(id)) callPos.set(id, i);
54373
+ else if (isOutput(t) && !outPos.has(id)) outPos.set(id, i);
54374
+ }
54375
+ if (callPos.size === 0) return items;
54376
+ const hoistBefore = new Array(n).fill(null);
54377
+ let anyTrapped = false;
54378
+ for (let p2 = 0; p2 < n; p2++) {
54379
+ const t = items[p2].type;
54380
+ if (isCall(t) || isOutput(t)) continue;
54381
+ let target = -1;
54382
+ for (const [id, c] of callPos) {
54383
+ const o = outPos.get(id);
54384
+ if (o === void 0 || !(c < p2 && o > p2)) continue;
54385
+ if (target === -1 || c < target) target = c;
54386
+ }
54387
+ if (target >= 0) {
54388
+ hoistBefore[p2] = target;
54389
+ anyTrapped = true;
54390
+ }
54391
+ }
54392
+ if (!anyTrapped) return items;
54393
+ const pendingByTarget = /* @__PURE__ */ new Map();
54394
+ for (let p2 = 0; p2 < n; p2++) {
54395
+ const target = hoistBefore[p2];
54396
+ if (target === null) continue;
54397
+ const batch = pendingByTarget.get(target);
54398
+ if (batch) batch.push(items[p2]);
54399
+ else pendingByTarget.set(target, [items[p2]]);
54400
+ }
54401
+ const result = [];
54402
+ for (let p2 = 0; p2 < n; p2++) {
54403
+ if (hoistBefore[p2] !== null) continue;
54404
+ const batch = pendingByTarget.get(p2);
54405
+ if (batch) result.push(...batch);
54406
+ result.push(items[p2]);
54407
+ }
54408
+ return result;
54409
+ }
54410
+
54351
54411
  // src/weak-overflow.ts
54352
54412
  var MIN_USAGE = 0.9;
54353
54413
  var WINDOW_MS = 15 * 60 * 1e3;
@@ -54489,6 +54549,79 @@ function warnCacheCollapse(session, input, cached) {
54489
54549
  );
54490
54550
  }
54491
54551
 
54552
+ // src/error-dump.ts
54553
+ import fs4 from "fs";
54554
+ var DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
54555
+ var failCount = 0;
54556
+ var lastFailLog = 0;
54557
+ function warnDumpFailure(err2) {
54558
+ failCount++;
54559
+ const now = Date.now();
54560
+ if (failCount === 1 || now - lastFailLog >= 6e4) {
54561
+ lastFailLog = now;
54562
+ const msg = err2 instanceof Error ? err2.message : String(err2);
54563
+ log("warn", `[dump] rejected-body dump failed (total ${failCount}x): ${msg}`);
54564
+ }
54565
+ }
54566
+ function dumpRejectedBody(status, sessionId, body) {
54567
+ if (process.env.BILI_DUMP_4XX !== "1") return null;
54568
+ const raw = typeof body === "string" ? body : body.toString("utf8");
54569
+ if (!raw) return null;
54570
+ try {
54571
+ const cap = Math.max(1024, Number(process.env.BILI_DUMP_4XX_MAX_BYTES) || DEFAULT_MAX_BYTES);
54572
+ let text;
54573
+ let marker = "";
54574
+ if (raw.length > cap) {
54575
+ text = raw.slice(0, cap);
54576
+ marker = `
54577
+ [truncated: ${raw.length - cap} more character(s)]
54578
+ `;
54579
+ } else {
54580
+ try {
54581
+ text = JSON.stringify(JSON.parse(raw), null, 2);
54582
+ } catch {
54583
+ text = raw;
54584
+ }
54585
+ }
54586
+ const dir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
54587
+ fs4.mkdirSync(dir, { recursive: true });
54588
+ const sid = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
54589
+ const out = `${dir}/err-${Date.now()}-${sid}-${status}.json`;
54590
+ fs4.writeFileSync(out, `${text}${marker}`);
54591
+ log("info", `[dump] upstream ${status} rejected body written to ${out}`);
54592
+ return out;
54593
+ } catch (err2) {
54594
+ warnDumpFailure(err2);
54595
+ return null;
54596
+ }
54597
+ }
54598
+
54599
+ // src/strict-echo.ts
54600
+ function isStrictReasoningEcho(session, upstreamOrigin) {
54601
+ if (session.metadata.strictReasoningEcho === true) return true;
54602
+ return upstreamOrigin !== void 0 && /deepseek/i.test(upstreamOrigin);
54603
+ }
54604
+ function normalizeStrictEchoReasoning(messages, enabled, log2, sessionId) {
54605
+ if (!enabled) return messages;
54606
+ let patched = 0;
54607
+ const out = messages.map((m2) => {
54608
+ if (m2.role !== "assistant") return m2;
54609
+ if (!Array.isArray(m2.tool_calls) || m2.tool_calls.length === 0) return m2;
54610
+ if (typeof m2.reasoning_content === "string") return m2;
54611
+ patched++;
54612
+ return { ...m2, reasoning_content: "" };
54613
+ });
54614
+ if (patched > 0) {
54615
+ log2("info", `[${sessionId}] strict-echo: injected blank reasoning_content on ${patched} assistant tool-call message(s) (#762)`);
54616
+ }
54617
+ return patched > 0 ? out : messages;
54618
+ }
54619
+ function normalizeStrictEchoBody(body, enabled, log2, sessionId) {
54620
+ if (!enabled || !Array.isArray(body.messages)) return body;
54621
+ const patched = normalizeStrictEchoReasoning(body.messages, true, log2, sessionId);
54622
+ return patched === body.messages ? body : { ...body, messages: patched };
54623
+ }
54624
+
54492
54625
  // src/util.ts
54493
54626
  import { createHash as createHash5 } from "crypto";
54494
54627
  function hashId2(s3) {
@@ -54603,6 +54736,7 @@ function shouldReserveOutputHeadroom(protocol) {
54603
54736
 
54604
54737
  // src/loop/core.ts
54605
54738
  var MAX_LOOP_ROUNDS = 10;
54739
+ var DEGENERATE_RETRY_NUDGE = "[billion-context] Your previous response ended with no visible text and no tool call. Continue now: take your next concrete action.";
54606
54740
  function isLoopThinking(m2) {
54607
54741
  return m2.contentType === "reasoning" && typeof m2.id === "string" && m2.id.startsWith("acp_loop_");
54608
54742
  }
@@ -54672,6 +54806,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54672
54806
  const coreMessages = [...ctx.messages];
54673
54807
  let degradedRetried = false;
54674
54808
  let truncationRetried = false;
54809
+ let degenerateRetried = false;
54675
54810
  const fetchUpstream = (body) => fetchWithRetry(
54676
54811
  requestOptions.url,
54677
54812
  {
@@ -54689,6 +54824,12 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54689
54824
  }
54690
54825
  );
54691
54826
  const failedSignatures = /* @__PURE__ */ new Set();
54827
+ let strictEchoOrigin;
54828
+ try {
54829
+ strictEchoOrigin = new URL(requestOptions.url).origin;
54830
+ } catch {
54831
+ strictEchoOrigin = void 0;
54832
+ }
54692
54833
  try {
54693
54834
  for (let round = 1; round <= MAX_LOOP_ROUNDS; round++) {
54694
54835
  if (signal?.aborted) break;
@@ -54702,6 +54843,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54702
54843
  let sawDone = false;
54703
54844
  let suppressCompletion = false;
54704
54845
  let truncatedDone = false;
54846
+ let sawThinking = false;
54705
54847
  let forwardedAny = false;
54706
54848
  const fwd = (chunk) => {
54707
54849
  forwardedAny = true;
@@ -54718,6 +54860,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54718
54860
  sawDone = false;
54719
54861
  suppressCompletion = false;
54720
54862
  truncatedDone = false;
54863
+ sawThinking = false;
54721
54864
  forwardedAny = false;
54722
54865
  for await (const ev of adapter.parseStream(currentUpstream, round)) {
54723
54866
  if (signal?.aborted) break;
@@ -54759,6 +54902,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54759
54902
  finishReason = ev.finishReason;
54760
54903
  suppressCompletion = ev.suppressCompletion === true;
54761
54904
  truncatedDone = ev.truncated === true;
54905
+ sawThinking = ev.thinking === true;
54762
54906
  } else if (ev.kind === "meta") {
54763
54907
  if (round === 1 || !ev.firstRoundOnly) {
54764
54908
  yield fwd(ev.chunk);
@@ -54787,6 +54931,37 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54787
54931
  }
54788
54932
  }
54789
54933
  }
54934
+ if (!degenerateRetried && sawDone && sawThinking && !truncatedDone && !suppressCompletion && typeof finishReason === "string" && finishReason !== "failed" && finishReason !== "incomplete" && finishReason !== "error" && assistantText.length === 0 && calls.length === 0 && !forwardedAny && !signal?.aborted) {
54935
+ degenerateRetried = true;
54936
+ ctx.log(`[acp-loop] round ${round}: degenerate terminal turn (completed, zero text/tool calls) invisible to client; retrying once with continuation nudge (#732)`);
54937
+ log("warn", `[acp-loop] degenerate-turn auto-retry round ${round} (session ${ctx.session.id})`);
54938
+ const nudge = {
54939
+ id: `acp_degenerate_retry_r${round}`,
54940
+ role: "user",
54941
+ contentType: "text",
54942
+ text: DEGENERATE_RETRY_NUDGE
54943
+ };
54944
+ try {
54945
+ const retryBody = adapter.buildRequest([...coreMessages, nudge], systemPrompt, requestBody);
54946
+ const respResult2 = await fetchUpstream(retryBody);
54947
+ if (!respResult2.response.body) {
54948
+ respResult2.clearTimer();
54949
+ throw new UpstreamHttpError(respResult2.response.status, "(empty response body)", 1);
54950
+ }
54951
+ currentUpstream = respResult2.response.body;
54952
+ roundBody = retryBody;
54953
+ if (activeClearTimer) activeClearTimer();
54954
+ activeClearTimer = respResult2.clearTimer;
54955
+ continue;
54956
+ } catch (e) {
54957
+ if (e instanceof UpstreamHttpError) {
54958
+ ctx.log(`[acp-loop] round ${round}: degenerate retry failed (upstream error ${e.status}: ${e.body.slice(0, 200)}); passing the empty turn through`);
54959
+ } else {
54960
+ ctx.log(`[acp-loop] round ${round}: degenerate retry failed (${e instanceof Error ? e.message : String(e)}); passing the empty turn through`);
54961
+ }
54962
+ log("warn", `[acp-loop] degenerate-turn auto-retry failed round ${round}: ${e instanceof Error ? e.message : String(e)}`);
54963
+ }
54964
+ }
54790
54965
  break;
54791
54966
  }
54792
54967
  if (usage.inputTokens !== void 0 || usage.outputTokens !== void 0 || usage.cachedTokens !== void 0) {
@@ -54964,13 +55139,14 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54964
55139
  ctx.log(`[acp-loop] round ${round}: proxy tool executed; re-requesting so the model sees the result`);
54965
55140
  if (signal?.aborted) break;
54966
55141
  let newBody = adapter.buildRequest(coreMessages, systemPrompt, requestBody);
55142
+ newBody = normalizeStrictEchoBody(newBody, isStrictReasoningEcho(ctx.session, strictEchoOrigin), (level, msg) => log(level, `[acp-loop] ${msg}`), ctx.session.id ?? "unknown");
54967
55143
  if (process.env.ACP_DUMP_BODY === "1") {
54968
55144
  try {
54969
- const fs13 = await import("fs");
55145
+ const fs14 = await import("fs");
54970
55146
  const dumpDir = process.env.ACP_DUMP_DIR || `${process.env.HOME}/.local/state/billion-context/dumps`;
54971
- fs13.mkdirSync(dumpDir, { recursive: true });
55147
+ fs14.mkdirSync(dumpDir, { recursive: true });
54972
55148
  const sid = ctx.session.id ?? "unknown";
54973
- fs13.writeFileSync(`${dumpDir}/req-${Date.now()}-${sid}-REREQUEST.json`, JSON.stringify(newBody, null, 2));
55149
+ fs14.writeFileSync(`${dumpDir}/req-${Date.now()}-${sid}-REREQUEST.json`, JSON.stringify(newBody, null, 2));
54974
55150
  } catch {
54975
55151
  }
54976
55152
  }
@@ -54998,6 +55174,9 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
54998
55174
  ctx.log(`[acp-loop] 400 mentions reasoning_content \u2014 learned strict reasoning echo for this session; #651 reasoning-drop disabled (#684)`);
54999
55175
  log("warn", `[acp-loop] learned strictReasoningEcho (session ${ctx.session.id}); reasoning-drop disabled (#684)`);
55000
55176
  }
55177
+ if (e.status >= 400 && e.status < 500) {
55178
+ dumpRejectedBody(e.status, ctx.session.id ?? "unknown", JSON.stringify(newBody));
55179
+ }
55001
55180
  const suffix = e.attempts > 1 ? ` after ${e.attempts} attempt(s)` : "";
55002
55181
  ctx.log(`[acp-proxy: compress loop upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)}]`);
55003
55182
  log("error", `[acp-loop] upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)}`);
@@ -55297,6 +55476,7 @@ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId
55297
55476
  } else {
55298
55477
  inputItems = coreToResponses(coreMessages, customToolCallIds);
55299
55478
  }
55479
+ inputItems = hoistTrappedToolItems(inputItems);
55300
55480
  const devParts = projection && projection.systemParts.length > 0 ? [...projection.systemParts, systemPrompt] : [systemPrompt];
55301
55481
  const withDev = injectResponsesDeveloperMessage(inputItems, devParts.join("\n\n---\n\n"));
55302
55482
  const rebuilt = { ...requestBody, input: withDev };
@@ -55477,7 +55657,7 @@ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId
55477
55657
  cachedTokens: typeof pd?.cached_tokens === "number" ? pd.cached_tokens : void 0
55478
55658
  };
55479
55659
  maybeWarnDegenerate("completed");
55480
- yield { kind: "done", finishReason: "completed" };
55660
+ yield { kind: "done", finishReason: "completed", thinking: sawReasoning };
55481
55661
  } else if (type === "response.incomplete") {
55482
55662
  yield* flushFilter();
55483
55663
  terminalKind = "incomplete";
@@ -55867,7 +56047,7 @@ function createOpenaiAdapter(requestBody, clientSystem, absorbName) {
55867
56047
  yield { kind: "meta", chunk: Buffer.from(eventStr + "\n\n", "utf8") };
55868
56048
  }
55869
56049
  maybeWarnDegenerate("stop");
55870
- yield { kind: "done", finishReason: "stop", ...sawRealToolCall ? { suppressCompletion: true } : {} };
56050
+ yield { kind: "done", finishReason: "stop", thinking: sawReasoning, ...sawRealToolCall ? { suppressCompletion: true } : {} };
55871
56051
  continue;
55872
56052
  }
55873
56053
  let parsed;
@@ -55913,13 +56093,14 @@ function createOpenaiAdapter(requestBody, clientSystem, absorbName) {
55913
56093
  const chunk = rawBuf;
55914
56094
  yield { kind: "meta", chunk };
55915
56095
  maybeWarnDegenerate(finishReason);
55916
- yield { kind: "done", finishReason, suppressCompletion: true };
56096
+ yield { kind: "done", finishReason, suppressCompletion: true, thinking: sawReasoning };
55917
56097
  continue;
55918
56098
  } else {
55919
56099
  maybeWarnDegenerate(finishReason);
55920
56100
  yield {
55921
56101
  kind: "done",
55922
- finishReason: hadToolCalls && finishReason === "stop" ? "tool_calls" : finishReason
56102
+ finishReason: hadToolCalls && finishReason === "stop" ? "tool_calls" : finishReason,
56103
+ thinking: sawReasoning
55923
56104
  };
55924
56105
  }
55925
56106
  }
@@ -56340,7 +56521,7 @@ ${systemPrompt}` : systemPrompt;
56340
56521
  };
56341
56522
  }
56342
56523
  maybeWarnDegenerate(stopReason);
56343
- yield { kind: "done", finishReason: stopReason };
56524
+ yield { kind: "done", finishReason: stopReason, thinking: sawThinking };
56344
56525
  } else if (type === "message_stop") {
56345
56526
  if (lastTextIndex !== null) {
56346
56527
  const tail = tagFilter.flush();
@@ -56359,7 +56540,7 @@ ${systemPrompt}` : systemPrompt;
56359
56540
  };
56360
56541
  }
56361
56542
  maybeWarnDegenerate(stopReason);
56362
- yield { kind: "done", finishReason: stopReason ?? "end_turn" };
56543
+ yield { kind: "done", finishReason: stopReason ?? "end_turn", thinking: sawThinking };
56363
56544
  } else if (round === 1) {
56364
56545
  yield { kind: "meta", chunk: rawBuf, firstRoundOnly: true };
56365
56546
  }
@@ -56530,7 +56711,16 @@ function surfaceReadonlyJson(current, proxyCalls, ctx) {
56530
56711
  }
56531
56712
  if (markers.length === 0) return current;
56532
56713
  const out = Array.isArray(current.output) ? [...current.output] : [];
56533
- out.push({ type: "message", id: `msg_acp_ro_${Date.now()}_${markers.length}`, role: "assistant", content: [{ type: "output_text", text: markers.join("\n") }] });
56714
+ const markerItem = { type: "message", id: `msg_acp_ro_${Date.now()}_${markers.length}`, role: "assistant", content: [{ type: "output_text", text: markers.join("\n") }] };
56715
+ let insertAt = out.length;
56716
+ for (let i = 0; i < out.length; i++) {
56717
+ const t = out[i]?.type;
56718
+ if (t === "function_call" || t === "custom_tool_call") {
56719
+ insertAt = i;
56720
+ break;
56721
+ }
56722
+ }
56723
+ out.splice(insertAt, 0, markerItem);
56534
56724
  return { ...current, output: out };
56535
56725
  }
56536
56726
  async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requestOptions) {
@@ -56565,7 +56755,7 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
56565
56755
  ctx.log(`[acp-proxy: responses JSON ${call.name} \u2192 ${result2.slice(0, 120).replace(/\n/g, " ")}]`);
56566
56756
  inputItems.push({ type: "message", role: "developer", content: buildVisibilityMarker(call.name, result2) });
56567
56757
  }
56568
- requestBody.input = inputItems;
56758
+ requestBody.input = hoistTrappedToolItems(inputItems);
56569
56759
  const result = await fetchWithRetry(requestOptions.url, {
56570
56760
  method: "POST",
56571
56761
  headers: requestOptions.headers,
@@ -57760,7 +57950,7 @@ var PrefixAffinityResolver = class {
57760
57950
  var prefixAffinity = new PrefixAffinityResolver();
57761
57951
 
57762
57952
  // src/affinity-persist.ts
57763
- import fs4 from "fs";
57953
+ import fs5 from "fs";
57764
57954
  import path11 from "path";
57765
57955
  var PERSIST_DEBOUNCE_MS = 5e3;
57766
57956
  function affinityFile() {
@@ -57775,9 +57965,9 @@ function writeSnapshot() {
57775
57965
  const file = affinityFile();
57776
57966
  const snapshot = { version: 1, entries: prefixAffinity.exportSnapshot() };
57777
57967
  const tmp = `${file}.tmp`;
57778
- fs4.mkdirSync(path11.dirname(file), { recursive: true });
57779
- fs4.writeFileSync(tmp, JSON.stringify(snapshot));
57780
- fs4.renameSync(tmp, file);
57968
+ fs5.mkdirSync(path11.dirname(file), { recursive: true });
57969
+ fs5.writeFileSync(tmp, JSON.stringify(snapshot));
57970
+ fs5.renameSync(tmp, file);
57781
57971
  } catch (e) {
57782
57972
  log("warn", `[prefix-affinity] persist failed (${e instanceof Error ? e.message : String(e)}); affinity survives in memory`);
57783
57973
  } finally {
@@ -57802,8 +57992,8 @@ function flushPrefixAffinity() {
57802
57992
  function hydratePrefixAffinity() {
57803
57993
  try {
57804
57994
  const file = affinityFile();
57805
- if (!fs4.existsSync(file)) return;
57806
- const parsed = JSON.parse(fs4.readFileSync(file, "utf8"));
57995
+ if (!fs5.existsSync(file)) return;
57996
+ const parsed = JSON.parse(fs5.readFileSync(file, "utf8"));
57807
57997
  const imported = prefixAffinity.importSnapshot(parsed.entries);
57808
57998
  if (imported > 0) log("info", `[prefix-affinity] hydrated ${imported} chain(s) from ${path11.basename(file)} \u2014 anonymous sessions reattach across restarts`);
57809
57999
  } catch (e) {
@@ -57954,13 +58144,13 @@ function buildStatusPanel(input) {
57954
58144
 
57955
58145
  // src/plugin.ts
57956
58146
  import { fileURLToPath as fileURLToPath3 } from "url";
57957
- import fs5 from "fs";
58147
+ import fs6 from "fs";
57958
58148
  import path12 from "path";
57959
58149
  var PROXY_VERSION = (() => {
57960
58150
  try {
57961
58151
  const here = fileURLToPath3(import.meta.url);
57962
58152
  const pkg = path12.join(path12.dirname(here), "..", "package.json");
57963
- return JSON.parse(fs5.readFileSync(pkg, "utf8")).version ?? "dev";
58153
+ return JSON.parse(fs6.readFileSync(pkg, "utf8")).version ?? "dev";
57964
58154
  } catch {
57965
58155
  return "dev";
57966
58156
  }
@@ -57973,7 +58163,7 @@ var VERSION2 = (() => {
57973
58163
  try {
57974
58164
  const here = fileURLToPath3(import.meta.url);
57975
58165
  const pkg = path12.join(path12.dirname(here), "..", "package.json");
57976
- return JSON.parse(fs5.readFileSync(pkg, "utf8")).version ?? "dev";
58166
+ return JSON.parse(fs6.readFileSync(pkg, "utf8")).version ?? "dev";
57977
58167
  } catch {
57978
58168
  return "dev";
57979
58169
  }
@@ -58010,11 +58200,11 @@ function writeConversationsFile() {
58010
58200
  try {
58011
58201
  const obj = {};
58012
58202
  for (const [k2, v2] of conversations) obj[k2] = v2;
58013
- fs5.mkdirSync(stateDir(), { recursive: true });
58203
+ fs6.mkdirSync(stateDir(), { recursive: true });
58014
58204
  const filePath = conversationsFile();
58015
58205
  const draft = `${filePath}.${process.pid}.bili-tmp`;
58016
- fs5.writeFileSync(draft, JSON.stringify(obj));
58017
- fs5.renameSync(draft, filePath);
58206
+ fs6.writeFileSync(draft, JSON.stringify(obj));
58207
+ fs6.renameSync(draft, filePath);
58018
58208
  conversationsDirty = false;
58019
58209
  } catch {
58020
58210
  }
@@ -58036,7 +58226,7 @@ function flushConversations() {
58036
58226
  function loadConversations() {
58037
58227
  let raw;
58038
58228
  try {
58039
- raw = fs5.readFileSync(conversationsFile(), "utf8");
58229
+ raw = fs6.readFileSync(conversationsFile(), "utf8");
58040
58230
  } catch {
58041
58231
  return;
58042
58232
  }
@@ -58049,7 +58239,7 @@ function loadConversations() {
58049
58239
  }
58050
58240
  } catch {
58051
58241
  try {
58052
- fs5.renameSync(conversationsFile(), `${conversationsFile()}.corrupt-${Date.now()}`);
58242
+ fs6.renameSync(conversationsFile(), `${conversationsFile()}.corrupt-${Date.now()}`);
58053
58243
  } catch {
58054
58244
  }
58055
58245
  log("warn", "[plugin] plugin-conversations.json is corrupt \u2014 backed up beside the original, starting an empty routing table");
@@ -58892,12 +59082,12 @@ async function pipePluginJson(stream2, res, session, protocol) {
58892
59082
  import tls3 from "tls";
58893
59083
 
58894
59084
  // src/discover.ts
58895
- import fs7 from "fs";
59085
+ import fs8 from "fs";
58896
59086
  import os2 from "os";
58897
59087
  import path14 from "path";
58898
59088
 
58899
59089
  // src/client-config.ts
58900
- import fs6 from "fs";
59090
+ import fs7 from "fs";
58901
59091
  import os from "os";
58902
59092
  import path13 from "path";
58903
59093
  function toModelWindow(id, contextWindow) {
@@ -58918,7 +59108,7 @@ function qoderIsCnSite(env = process.env) {
58918
59108
  const cnDir = path13.join(h, ".qoder-cn");
58919
59109
  const intlDir = path13.join(h, ".qoder");
58920
59110
  try {
58921
- if (fs6.existsSync(cnDir) && !fs6.existsSync(intlDir)) return true;
59111
+ if (fs7.existsSync(cnDir) && !fs7.existsSync(intlDir)) return true;
58922
59112
  } catch {
58923
59113
  }
58924
59114
  return false;
@@ -58957,7 +59147,7 @@ function nonEmpty2(s3) {
58957
59147
  }
58958
59148
  function readJsonObject(filePath) {
58959
59149
  try {
58960
- const txt = fs6.readFileSync(filePath, "utf8");
59150
+ const txt = fs7.readFileSync(filePath, "utf8");
58961
59151
  const parsed = JSON.parse(txt);
58962
59152
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
58963
59153
  } catch {
@@ -59031,7 +59221,7 @@ function parseCodebuddyModelsJson(obj) {
59031
59221
  }
59032
59222
  function readJsonFile(filePath) {
59033
59223
  try {
59034
- return JSON.parse(fs6.readFileSync(filePath, "utf8"));
59224
+ return JSON.parse(fs7.readFileSync(filePath, "utf8"));
59035
59225
  } catch {
59036
59226
  return null;
59037
59227
  }
@@ -59093,7 +59283,7 @@ function parseDshSettingsYaml(text) {
59093
59283
  function readDshConfig(dshHome) {
59094
59284
  let text;
59095
59285
  try {
59096
- text = fs6.readFileSync(path13.join(dshHome, "settings.yaml"), "utf8");
59286
+ text = fs7.readFileSync(path13.join(dshHome, "settings.yaml"), "utf8");
59097
59287
  } catch {
59098
59288
  return { baseUrls: [] };
59099
59289
  }
@@ -59195,7 +59385,7 @@ function readCodexConfig(codexHome) {
59195
59385
  const cfgPath = path13.join(codexHome, "config.toml");
59196
59386
  let text;
59197
59387
  try {
59198
- text = fs6.readFileSync(cfgPath, "utf8");
59388
+ text = fs7.readFileSync(cfgPath, "utf8");
59199
59389
  } catch {
59200
59390
  return { providers: {} };
59201
59391
  }
@@ -59279,7 +59469,7 @@ function readKimiConfig(kimiHome, env = process.env) {
59279
59469
  const cfgPath = path13.join(kimiHome, "config.toml");
59280
59470
  let text;
59281
59471
  try {
59282
- text = fs6.readFileSync(cfgPath, "utf8");
59472
+ text = fs7.readFileSync(cfgPath, "utf8");
59283
59473
  } catch {
59284
59474
  return { providers: {} };
59285
59475
  }
@@ -59380,7 +59570,7 @@ function readOmpConfig(ompHome) {
59380
59570
  const cfgPath = path13.join(ompHome, "models.yml");
59381
59571
  let text;
59382
59572
  try {
59383
- text = fs6.readFileSync(cfgPath, "utf8");
59573
+ text = fs7.readFileSync(cfgPath, "utf8");
59384
59574
  } catch {
59385
59575
  return { providers: {} };
59386
59576
  }
@@ -59461,7 +59651,7 @@ function readHermesConfig(hermesHome) {
59461
59651
  const cfgPath = path13.join(hermesHome, "config.yaml");
59462
59652
  let text;
59463
59653
  try {
59464
- text = fs6.readFileSync(cfgPath, "utf8");
59654
+ text = fs7.readFileSync(cfgPath, "utf8");
59465
59655
  } catch {
59466
59656
  return { providers: {} };
59467
59657
  }
@@ -59475,7 +59665,7 @@ function resolveOpencodeConfigFile(env) {
59475
59665
  function readOpencodeConfig(file) {
59476
59666
  let text;
59477
59667
  try {
59478
- text = fs6.readFileSync(file, "utf8");
59668
+ text = fs7.readFileSync(file, "utf8");
59479
59669
  } catch {
59480
59670
  return { providers: {} };
59481
59671
  }
@@ -59535,7 +59725,7 @@ function readZcodeConfig(zcodeHome) {
59535
59725
  const cfgPath = path13.join(zcodeHome, "v2", "config.json");
59536
59726
  let txt;
59537
59727
  try {
59538
- txt = fs6.readFileSync(cfgPath, "utf8");
59728
+ txt = fs7.readFileSync(cfgPath, "utf8");
59539
59729
  } catch {
59540
59730
  return { providers: {} };
59541
59731
  }
@@ -59661,7 +59851,7 @@ function readMtimes(paths) {
59661
59851
  const mtimes = /* @__PURE__ */ new Map();
59662
59852
  for (const p2 of paths) {
59663
59853
  try {
59664
- const st2 = fs7.statSync(p2);
59854
+ const st2 = fs8.statSync(p2);
59665
59855
  mtimes.set(p2, st2.mtimeMs);
59666
59856
  } catch {
59667
59857
  }
@@ -60882,7 +61072,7 @@ Content-Length: ${Buffer.byteLength(body)}\r
60882
61072
  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;
60883
61073
  const origin = `http://${originHost}:${actualPort}`;
60884
61074
  try {
60885
- fs8.mkdirSync(stateDir(), { recursive: true });
61075
+ fs9.mkdirSync(stateDir(), { recursive: true });
60886
61076
  hydratePrefixAffinity();
60887
61077
  atomicWriteInstanceFile({
60888
61078
  origin,
@@ -61303,14 +61493,14 @@ async function handle(req, res, opts, core, config, log2, instanceId, instanceSt
61303
61493
  try {
61304
61494
  const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
61305
61495
  try {
61306
- fs8.mkdirSync(rawDir, { recursive: true });
61496
+ fs9.mkdirSync(rawDir, { recursive: true });
61307
61497
  } catch {
61308
61498
  }
61309
61499
  const hdrs = maskHeadersForLog(
61310
61500
  Object.fromEntries(Object.entries(req.headers).map(([k2, v2]) => [k2, Array.isArray(v2) ? v2.join(",") : String(v2)]))
61311
61501
  );
61312
61502
  const hdrText = Object.entries(hdrs).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
61313
- fs8.writeFileSync(`${rawDir}/${Date.now()}-INCOMING.txt`, `${req.method} ${maskUrlsInText(req.url ?? "")}
61503
+ fs9.writeFileSync(`${rawDir}/${Date.now()}-INCOMING.txt`, `${req.method} ${maskUrlsInText(req.url ?? "")}
61314
61504
  ${hdrText}
61315
61505
 
61316
61506
  ${bodyBuffer.toString("utf8")}`);
@@ -61654,17 +61844,13 @@ function withReasoningDrop(msgs, reasoning, log2, sessionId, strictEcho) {
61654
61844
  }
61655
61845
  return out;
61656
61846
  }
61657
- function isStrictReasoningEcho(session, upstreamOrigin) {
61658
- if (session.metadata.strictReasoningEcho === true) return true;
61659
- return upstreamOrigin !== void 0 && /deepseek/i.test(upstreamOrigin);
61660
- }
61661
61847
  function warnReasoningPairs(wireMessages, log2, sessionId) {
61662
61848
  let withRc = 0;
61663
61849
  let split = 0;
61664
61850
  for (const m2 of wireMessages) {
61665
61851
  const msg = m2;
61666
61852
  if (msg?.role !== "assistant") continue;
61667
- const hasRc = typeof msg.reasoning_content === "string" && msg.reasoning_content.length > 0;
61853
+ const hasRc = typeof msg.reasoning_content === "string";
61668
61854
  if (hasRc) withRc++;
61669
61855
  else if (Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) split++;
61670
61856
  }
@@ -61844,9 +62030,9 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, surface, log
61844
62030
  applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
61845
62031
  reapOrphanBlocks(session, msgs, deactivateBlock);
61846
62032
  rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
61847
- systemOut = injectSystem(parsed, opts, prompts, loopConfig);
62033
+ systemOut = injectSystem(parsed, opts, prompts, loopConfig, surface);
61848
62034
  if (injectTools) {
61849
- toolsOut = injectTool(parsed.tools, absorbActive ? ABSORB_TOOL : void 0);
62035
+ toolsOut = injectTool(parsed.tools, absorbActive ? ABSORB_TOOL : void 0, surface?.toolPrompts);
61850
62036
  }
61851
62037
  if (willInjectNudge && turn.nudge) {
61852
62038
  try {
@@ -61976,7 +62162,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, surface, log2,
61976
62162
  rebuiltMessages = injectOpenaiSystem(rebuiltMessages, sysParts);
61977
62163
  openaiOutboundSystem = sysParts.join("\n\n");
61978
62164
  if (injectTools) {
61979
- toolsOut = injectOpenaiTool(parsed.tools, absorbActive ? ABSORB_TOOL_OPENAI : void 0);
62165
+ toolsOut = injectOpenaiTool(parsed.tools, absorbActive ? ABSORB_TOOL_OPENAI : void 0, surface?.toolPrompts);
61980
62166
  }
61981
62167
  if (willInjectNudge && turn.nudge) {
61982
62168
  try {
@@ -61991,6 +62177,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, surface, log2,
61991
62177
  log2("warn", `[${sessionId}] kernel transform failed, forwarding unchanged: ${String(err2)}`);
61992
62178
  processedMessages = [];
61993
62179
  }
62180
+ rebuiltMessages = normalizeStrictEchoReasoning(rebuiltMessages, isStrictReasoningEcho(session, upstreamOrigin), log2, sessionId);
61994
62181
  const rebuilt = { ...parsed, messages: rebuiltMessages, tools: toolsOut };
61995
62182
  warnReasoningPairs(rebuiltMessages, log2, sessionId);
61996
62183
  clampOutgoingOutput(rebuilt, typeof parsed.max_completion_tokens === "number" ? "max_completion_tokens" : "max_tokens", { systemText: openaiSystemText, tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow, imageTokens: imageTokensInParsedBody("openai", rebuilt, imageBillingFor(opts, billingUpstream ?? upstreamOrigin)) }, sessionId, log2);
@@ -62077,6 +62264,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, surface, log
62077
62264
  processedMessages = repairResponsesAssistantOrdering(stripReasoning(stripKernelSummaries(turn.messages, turn.state)), originalMessages);
62078
62265
  reapOrphanBlocks(session, msgs, deactivateBlock);
62079
62266
  rebuiltInput = patchResponsesInput(projection, processedMessages);
62267
+ if (Array.isArray(rebuiltInput)) rebuiltInput = hoistTrappedToolItems(rebuiltInput);
62080
62268
  const forgedSummaries = echoReplaced ? [] : session.metadata.codexForgedSummaries ?? [];
62081
62269
  if (shouldInject && !isCompactionTrigger && !process.env.ACP_NO_COMPRESS_PROMPT) {
62082
62270
  const prompt = withMarkerIntegrityNote(responsesTextProtocol ? buildCompressHybridSystemPrompt(prompts, surface?.promptSections) : buildCompressSystemPrompt(prompts, surface?.promptSections));
@@ -62086,7 +62274,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, surface, log
62086
62274
  responsesDevContent = devContent;
62087
62275
  rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
62088
62276
  if (!process.env.ACP_NO_INJECT_TOOL && injectTools) {
62089
- toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES) : injectResponsesTool(parsed.tools, absorbActive ? [...ACP_TOOLS_RESPONSES, ABSORB_TOOL_RESPONSES] : ACP_TOOLS_RESPONSES);
62277
+ toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES, surface?.toolPrompts) : injectResponsesTool(parsed.tools, absorbActive ? [...ACP_TOOLS_RESPONSES, ABSORB_TOOL_RESPONSES] : ACP_TOOLS_RESPONSES, surface?.toolPrompts);
62090
62278
  }
62091
62279
  } else if (projection.systemParts.length > 0 || forgedSummaries.length > 0) {
62092
62280
  const devContent = [...projection.systemParts, ...forgedSummaries].join("\n\n---\n\n");
@@ -62242,11 +62430,12 @@ function prepareResponsesCompact(body, parsed, session, req, core, config, log2)
62242
62430
  }
62243
62431
  const viewed = applyAbsorbView(turn.messages, turn.state, compactConfig, session.stats.lastInputTokens);
62244
62432
  const processed = repairResponsesAssistantOrdering(stripKernelSummaries(viewed, turn.state), projection.msgs);
62245
- const output = patchResponsesInput(projection, processed);
62433
+ let output = patchResponsesInput(projection, processed);
62246
62434
  if (typeof output === "string") {
62247
62435
  session.state = prevState;
62248
62436
  return base;
62249
62437
  }
62438
+ output = hoistTrappedToolItems(output);
62250
62439
  snapshotMessages(session, projection.msgs);
62251
62440
  markDirty(session);
62252
62441
  log2("info", `[${session.id}] codex compact intercepted (endpoint); forged history with ${output.length} item(s), upstream not contacted`);
@@ -62600,16 +62789,16 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
62600
62789
  if (bodyDumpEnabled() && process.env.ACP_DUMP_REQ !== "0") {
62601
62790
  const dumpDir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
62602
62791
  try {
62603
- fs8.mkdirSync(dumpDir, { recursive: true });
62792
+ fs9.mkdirSync(dumpDir, { recursive: true });
62604
62793
  } catch {
62605
62794
  }
62606
62795
  const sid = prepared?.session.id ?? "unknown";
62607
62796
  const out = `${dumpDir}/req-${Date.now()}-${safeSessionId(sid)}.json`;
62608
62797
  try {
62609
62798
  const pretty = JSON.stringify(JSON.parse(wireBody), null, 2);
62610
- fs8.writeFileSync(out, pretty);
62799
+ fs9.writeFileSync(out, pretty);
62611
62800
  } catch {
62612
- fs8.writeFileSync(out, wireBody);
62801
+ fs9.writeFileSync(out, wireBody);
62613
62802
  }
62614
62803
  log2("info", `[debug] forwarded body written to ${out}`);
62615
62804
  }
@@ -62629,7 +62818,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
62629
62818
  const rawBase = bodyDumpEnabled() ? (() => {
62630
62819
  try {
62631
62820
  const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
62632
- fs8.mkdirSync(rawDir, { recursive: true });
62821
+ fs9.mkdirSync(rawDir, { recursive: true });
62633
62822
  return `${rawDir}/${Date.now()}-${safeSessionId(prepared?.session.id)}`;
62634
62823
  } catch {
62635
62824
  return "";
@@ -62640,7 +62829,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
62640
62829
  const hdrText = Object.entries(maskHeadersForLog(headers)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
62641
62830
  const bodyText = req.method === "GET" || req.method === "HEAD" ? "" : typeof wireBody === "string" ? wireBody : Buffer.from(wireBody).toString("utf8");
62642
62831
  const reqPath = `${rawBase}-REQ.txt`;
62643
- fs8.writeFileSync(reqPath, `${req.method ?? "POST"} ${maskUrlForLog(upstreamUrl)}
62832
+ fs9.writeFileSync(reqPath, `${req.method ?? "POST"} ${maskUrlForLog(upstreamUrl)}
62644
62833
  ${hdrText}
62645
62834
 
62646
62835
  ${bodyText}`);
@@ -62752,7 +62941,7 @@ ${bodyText}`);
62752
62941
  try {
62753
62942
  const hdrText = Object.entries(maskHeadersForLog(respHeaders)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
62754
62943
  const resPath = `${rawBase}-RES.txt`;
62755
- fs8.writeFileSync(resPath, `${upstream.status}
62944
+ fs9.writeFileSync(resPath, `${upstream.status}
62756
62945
  ${hdrText}
62757
62946
  `);
62758
62947
  log2("info", `[debug] RAW response dump: ${resPath}`);
@@ -62811,6 +63000,13 @@ ${hdrText}
62811
63000
  }
62812
63001
  markDirty(s3);
62813
63002
  }
63003
+ if (upstream.status === 400 && /reasoning_content/i.test(errBody.toString("utf8"))) {
63004
+ if (s3.metadata.strictReasoningEcho !== true) {
63005
+ s3.metadata.strictReasoningEcho = true;
63006
+ markDirty(s3);
63007
+ log2("warn", `[${s3.id}] upstream 400 mentions reasoning_content \u2014 learned strictReasoningEcho for this session (#684/#762); reasoning-drop disabled`);
63008
+ }
63009
+ }
62814
63010
  }
62815
63011
  if (prepared?.session && upstream.status >= 500) {
62816
63012
  armFailureShrink(prepared, log2, `upstream ${upstream.status}`);
@@ -62823,6 +63019,9 @@ ${hdrText}
62823
63019
  if (bodyText.length > 600) snippet += " \u2026";
62824
63020
  if (!snippet) snippet = "(no body)";
62825
63021
  log("warn", `[${errSid}] \u2190 upstream ${upstream.status}${reqIdText}: ${snippet}`);
63022
+ if (upstream.status >= 400 && upstream.status < 500) {
63023
+ dumpRejectedBody(upstream.status, errSid, wireBody);
63024
+ }
62826
63025
  if (res.headersSent) {
62827
63026
  if (prepared?.stream) {
62828
63027
  emitStreamError(res, prepared.protocol, `upstream HTTP ${upstream.status}: ${snippet}`, (m2) => log("info", m2));
@@ -65227,7 +65426,7 @@ var hr = /* @__PURE__ */ Symbol("entry");
65227
65426
  var cs = /* @__PURE__ */ Symbol("entryOpt");
65228
65427
  var ui = /* @__PURE__ */ Symbol("writeEntryClass");
65229
65428
  var lr = /* @__PURE__ */ Symbol("write");
65230
- var fs9 = /* @__PURE__ */ Symbol("ondrain");
65429
+ var fs10 = /* @__PURE__ */ Symbol("ondrain");
65231
65430
  var wt = class extends A {
65232
65431
  sync = false;
65233
65432
  opt;
@@ -65261,8 +65460,8 @@ var wt = class extends A {
65261
65460
  if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
65262
65461
  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");
65263
65462
  let e = this.zip;
65264
- e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs9]()), this.on("resume", () => e.resume());
65265
- } else this.on("drain", this[fs9]);
65463
+ e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs10]()), this.on("resume", () => e.resume());
65464
+ } else this.on("drain", this[fs10]);
65266
65465
  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;
65267
65466
  }
65268
65467
  [lr](t) {
@@ -65375,7 +65574,7 @@ var wt = class extends A {
65375
65574
  this.emit("error", e);
65376
65575
  }
65377
65576
  }
65378
- [fs9]() {
65577
+ [fs10]() {
65379
65578
  this[Et] && this[Et].entry && this[Et].entry.resume();
65380
65579
  }
65381
65580
  [di](t) {
@@ -66733,14 +66932,14 @@ function startAutoUpdate(opts) {
66733
66932
  }
66734
66933
 
66735
66934
  // src/mcp.ts
66736
- import fs10 from "fs";
66935
+ import fs11 from "fs";
66737
66936
  import path16 from "path";
66738
66937
  import { fileURLToPath as fileURLToPath5 } from "url";
66739
66938
  var VERSION3 = (() => {
66740
66939
  try {
66741
66940
  const here = fileURLToPath5(import.meta.url);
66742
66941
  const pkg = path16.join(path16.dirname(here), "..", "package.json");
66743
- return JSON.parse(fs10.readFileSync(pkg, "utf8")).version ?? "dev";
66942
+ return JSON.parse(fs11.readFileSync(pkg, "utf8")).version ?? "dev";
66744
66943
  } catch {
66745
66944
  return "dev";
66746
66945
  }
@@ -66945,7 +67144,7 @@ if (process.argv[1] && /(?:^|[\\/])mcp\.(?:ts|js)$/.test(process.argv[1])) {
66945
67144
  }
66946
67145
 
66947
67146
  // src/plugin-install.ts
66948
- import fs11 from "fs";
67147
+ import fs12 from "fs";
66949
67148
  import path17 from "path";
66950
67149
  import os4 from "os";
66951
67150
  import { execFileSync as execFileSync2 } from "child_process";
@@ -66973,14 +67172,14 @@ function homeFile(rel2, envOverride) {
66973
67172
  return path17.join(base, rel2);
66974
67173
  }
66975
67174
  function backupOnce(file) {
66976
- if (fs11.existsSync(file) && !fs11.existsSync(`${file}.bili-bak`)) {
66977
- fs11.copyFileSync(file, `${file}.bili-bak`);
67175
+ if (fs12.existsSync(file) && !fs12.existsSync(`${file}.bili-bak`)) {
67176
+ fs12.copyFileSync(file, `${file}.bili-bak`);
66978
67177
  }
66979
67178
  }
66980
67179
  function readJson(file) {
66981
67180
  let text;
66982
67181
  try {
66983
- text = fs11.readFileSync(file, "utf8");
67182
+ text = fs12.readFileSync(file, "utf8");
66984
67183
  } catch (err2) {
66985
67184
  if (err2.code === "ENOENT") return {};
66986
67185
  throw err2;
@@ -66997,12 +67196,12 @@ function readJson(file) {
66997
67196
  return parsed;
66998
67197
  }
66999
67198
  function writeJson(file, data) {
67000
- fs11.mkdirSync(path17.dirname(file), { recursive: true });
67199
+ fs12.mkdirSync(path17.dirname(file), { recursive: true });
67001
67200
  backupOnce(file);
67002
- fs11.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
67201
+ fs12.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
67003
67202
  }
67004
67203
  function requireDistFile(file) {
67005
- if (!fs11.existsSync(file)) {
67204
+ if (!fs12.existsSync(file)) {
67006
67205
  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
67007
67206
  `);
67008
67207
  }
@@ -67090,13 +67289,13 @@ function ompBlockLoaded(text) {
67090
67289
  const lines = text.split("\n");
67091
67290
  return ompExtensionItemLines(text).some((i) => {
67092
67291
  const v2 = ompEntryValue(lines[i]);
67093
- return OMP_ENTRY_RE.test(v2) && fs11.existsSync(v2);
67292
+ return OMP_ENTRY_RE.test(v2) && fs12.existsSync(v2);
67094
67293
  });
67095
67294
  }
67096
67295
  function ompRemove() {
67097
67296
  const file = ompConfigFile();
67098
- if (!fs11.existsSync(file)) return `omp: not installed (${file})`;
67099
- const text = fs11.readFileSync(file, "utf8");
67297
+ if (!fs12.existsSync(file)) return `omp: not installed (${file})`;
67298
+ const text = fs12.readFileSync(file, "utf8");
67100
67299
  const lines = text.split("\n");
67101
67300
  const drop = new Set(
67102
67301
  ompExtensionItemLines(text).filter((i) => OMP_ENTRY_RE.test(ompEntryValue(lines[i])))
@@ -67104,15 +67303,15 @@ function ompRemove() {
67104
67303
  if (drop.size === 0) return `omp: not installed (${file})`;
67105
67304
  const cleaned = lines.filter((_2, i) => !drop.has(i)).join("\n");
67106
67305
  backupOnce(file);
67107
- fs11.writeFileSync(file, cleaned);
67306
+ fs12.writeFileSync(file, cleaned);
67108
67307
  return `omp: removed from ${file}`;
67109
67308
  }
67110
67309
  function ompInstall() {
67111
67310
  const file = ompConfigFile();
67112
67311
  const entry = ompExtensionPath();
67113
67312
  requireDistFile(entry);
67114
- fs11.mkdirSync(path17.dirname(file), { recursive: true });
67115
- let text = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
67313
+ fs12.mkdirSync(path17.dirname(file), { recursive: true });
67314
+ let text = fs12.existsSync(file) ? fs12.readFileSync(file, "utf8") : "";
67116
67315
  if (ompBlockLoaded(text)) return `omp: already installed (${file})`;
67117
67316
  {
67118
67317
  const lines = text.split("\n");
@@ -67154,25 +67353,25 @@ ${tail}`;
67154
67353
  throw new Error(`${file}: edit would leave ${occurrences} copies of the entry \u2014 aborting without writing`);
67155
67354
  }
67156
67355
  backupOnce(file);
67157
- fs11.writeFileSync(file, out);
67356
+ fs12.writeFileSync(file, out);
67158
67357
  return `omp: installed -> ${file} extensions += ${entry}`;
67159
67358
  }
67160
67359
  function ompStatus() {
67161
67360
  const file = ompConfigFile();
67162
- const text = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
67361
+ const text = fs12.existsSync(file) ? fs12.readFileSync(file, "utf8") : "";
67163
67362
  const lines = text.split("\n");
67164
67363
  let broken = false;
67165
67364
  for (const i of ompExtensionItemLines(text)) {
67166
67365
  const v2 = ompEntryValue(lines[i]);
67167
67366
  if (!OMP_ENTRY_RE.test(v2)) continue;
67168
- if (fs11.existsSync(v2)) return "installed";
67367
+ if (fs12.existsSync(v2)) return "installed";
67169
67368
  broken = true;
67170
67369
  }
67171
67370
  return broken ? "broken" : "not installed";
67172
67371
  }
67173
67372
  function ompPluginLoadedFrom(ompHome) {
67174
67373
  try {
67175
- return ompBlockLoaded(fs11.readFileSync(path17.join(ompHome, "config.yml"), "utf8"));
67374
+ return ompBlockLoaded(fs12.readFileSync(path17.join(ompHome, "config.yml"), "utf8"));
67176
67375
  } catch {
67177
67376
  return false;
67178
67377
  }
@@ -67226,7 +67425,7 @@ function malformedCodexArgs(block) {
67226
67425
  }
67227
67426
  function codexInstall() {
67228
67427
  const file = codexToml();
67229
- const text = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
67428
+ const text = fs12.existsSync(file) ? fs12.readFileSync(file, "utf8") : "";
67230
67429
  const existing = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
67231
67430
  if (existing !== null) {
67232
67431
  const block = text.slice(existing.index, text.indexOf("\n[", existing.index + 1) === -1 ? void 0 : text.indexOf("\n[", existing.index + 1));
@@ -67234,19 +67433,19 @@ function codexInstall() {
67234
67433
  if (block.trimEnd() === canonical.trimEnd()) return `codex: already installed (${file})`;
67235
67434
  const refreshed = text.slice(0, existing.index) + canonical + text.slice(existing.index + block.length);
67236
67435
  backupOnce(file);
67237
- fs11.writeFileSync(file, refreshed);
67436
+ fs12.writeFileSync(file, refreshed);
67238
67437
  const healed = malformedCodexArgs(block) ? " (repaired args: was not an array)" : "";
67239
67438
  return `codex: refreshed [mcp_servers.bili] -> ${file}${healed}`;
67240
67439
  }
67241
- fs11.mkdirSync(path17.dirname(file), { recursive: true });
67440
+ fs12.mkdirSync(path17.dirname(file), { recursive: true });
67242
67441
  backupOnce(file);
67243
- fs11.writeFileSync(file, text + (text.endsWith("\n") || text.length === 0 ? "" : "\n") + codexBlock());
67442
+ fs12.writeFileSync(file, text + (text.endsWith("\n") || text.length === 0 ? "" : "\n") + codexBlock());
67244
67443
  return `codex: installed -> ${file} [mcp_servers.bili]`;
67245
67444
  }
67246
67445
  function codexRemove() {
67247
67446
  const file = codexToml();
67248
- if (!fs11.existsSync(file)) return `codex: not installed (${file})`;
67249
- const text = fs11.readFileSync(file, "utf8");
67447
+ if (!fs12.existsSync(file)) return `codex: not installed (${file})`;
67448
+ const text = fs12.readFileSync(file, "utf8");
67250
67449
  const start = (() => {
67251
67450
  const m2 = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
67252
67451
  return m2 === null ? -1 : m2.index;
@@ -67259,11 +67458,11 @@ function codexRemove() {
67259
67458
  const end = nextTable >= 0 ? start + firstNewline + 1 + nextTable : text.length;
67260
67459
  const cleaned = (text.slice(0, lineStart).replace(/\n+$/, "\n") + text.slice(end)).replace(/^\n+/, "");
67261
67460
  backupOnce(file);
67262
- fs11.writeFileSync(file, cleaned);
67461
+ fs12.writeFileSync(file, cleaned);
67263
67462
  return `codex: removed from ${file}`;
67264
67463
  }
67265
67464
  function codexStatus() {
67266
- const text = fs11.existsSync(codexToml()) ? fs11.readFileSync(codexToml(), "utf8") : "";
67465
+ const text = fs12.existsSync(codexToml()) ? fs12.readFileSync(codexToml(), "utf8") : "";
67267
67466
  return /^\[mcp_servers\.bili\]\s*$/m.test(text) ? "installed" : "not installed";
67268
67467
  }
67269
67468
  function opencodeJson() {
@@ -67327,7 +67526,7 @@ function pluginStatusAll() {
67327
67526
 
67328
67527
  // src/launcher.ts
67329
67528
  import { randomUUID as randomUUID5 } from "crypto";
67330
- import fs12 from "fs";
67529
+ import fs13 from "fs";
67331
67530
  import net2 from "net";
67332
67531
  import os5 from "os";
67333
67532
  import path18 from "path";
@@ -67795,7 +67994,7 @@ function overlayLockPath(overlay) {
67795
67994
  function livePidHoldsOverlay(overlay) {
67796
67995
  let raw;
67797
67996
  try {
67798
- raw = fs12.readFileSync(overlayLockPath(overlay), "utf8");
67997
+ raw = fs13.readFileSync(overlayLockPath(overlay), "utf8");
67799
67998
  } catch {
67800
67999
  return void 0;
67801
68000
  }
@@ -67813,13 +68012,13 @@ function linkOverlayEntry(realHome, overlay, entry) {
67813
68012
  const link = path18.join(overlay, entry);
67814
68013
  let st2;
67815
68014
  try {
67816
- st2 = fs12.lstatSync(target);
68015
+ st2 = fs13.lstatSync(target);
67817
68016
  } catch {
67818
68017
  return false;
67819
68018
  }
67820
68019
  const kind = st2.isDirectory() ? process.platform === "win32" ? "junction" : "dir" : "file";
67821
68020
  try {
67822
- fs12.symlinkSync(target, link, kind);
68021
+ fs13.symlinkSync(target, link, kind);
67823
68022
  return true;
67824
68023
  } catch (err2) {
67825
68024
  const code = err2.code;
@@ -67827,18 +68026,18 @@ function linkOverlayEntry(realHome, overlay, entry) {
67827
68026
  }
67828
68027
  if (st2.isDirectory()) {
67829
68028
  try {
67830
- fs12.symlinkSync(target, link, "junction");
68029
+ fs13.symlinkSync(target, link, "junction");
67831
68030
  return true;
67832
68031
  } catch {
67833
68032
  return false;
67834
68033
  }
67835
68034
  }
67836
68035
  try {
67837
- fs12.linkSync(target, link);
68036
+ fs13.linkSync(target, link);
67838
68037
  return true;
67839
68038
  } catch {
67840
68039
  try {
67841
- fs12.copyFileSync(target, link);
68040
+ fs13.copyFileSync(target, link);
67842
68041
  return true;
67843
68042
  } catch {
67844
68043
  return false;
@@ -67848,7 +68047,7 @@ function linkOverlayEntry(realHome, overlay, entry) {
67848
68047
  function isWriteThroughHardlink(overlayPath, realPath, st2) {
67849
68048
  if (st2.isDirectory() || st2.isSymbolicLink() || st2.nlink <= 1) return false;
67850
68049
  try {
67851
- const realSt = fs12.lstatSync(realPath);
68050
+ const realSt = fs13.lstatSync(realPath);
67852
68051
  return st2.dev === realSt.dev && st2.ino === realSt.ino;
67853
68052
  } catch {
67854
68053
  return false;
@@ -67862,7 +68061,7 @@ function freeConflictName(dst) {
67862
68061
  let n = 1;
67863
68062
  while (n < 1e5) {
67864
68063
  try {
67865
- fs12.lstatSync(candidate);
68064
+ fs13.lstatSync(candidate);
67866
68065
  candidate = `${dst}.bili-conflict.${n}`;
67867
68066
  n += 1;
67868
68067
  } catch {
@@ -67875,7 +68074,7 @@ function mergeSqliteSet(overlay, realHome, base) {
67875
68074
  const members = sqliteSetMembers(base);
67876
68075
  const statFile = (dir, m2) => {
67877
68076
  try {
67878
- const st2 = fs12.lstatSync(path18.join(dir, m2));
68077
+ const st2 = fs13.lstatSync(path18.join(dir, m2));
67879
68078
  return st2.isFile() ? st2 : void 0;
67880
68079
  } catch {
67881
68080
  return void 0;
@@ -67901,22 +68100,22 @@ function mergeSqliteSet(overlay, realHome, base) {
67901
68100
  const movePreserving = (src, dst) => {
67902
68101
  let dstStat;
67903
68102
  try {
67904
- dstStat = fs12.lstatSync(dst);
68103
+ dstStat = fs13.lstatSync(dst);
67905
68104
  } catch {
67906
68105
  }
67907
68106
  if (dstStat) {
67908
68107
  if (dstStat.isDirectory()) throw new Error("target is a directory");
67909
68108
  const conflict = freeConflictName(dst);
67910
- fs12.renameSync(dst, conflict);
67911
- undo.push(() => fs12.renameSync(conflict, dst));
68109
+ fs13.renameSync(dst, conflict);
68110
+ undo.push(() => fs13.renameSync(conflict, dst));
67912
68111
  }
67913
- fs12.renameSync(src, dst);
67914
- undo.push(() => fs12.renameSync(dst, src));
68112
+ fs13.renameSync(src, dst);
68113
+ undo.push(() => fs13.renameSync(dst, src));
67915
68114
  };
67916
68115
  const preserveAsConflict = (src, name) => {
67917
68116
  const conflict = freeConflictName(path18.join(realHome, name));
67918
- fs12.renameSync(src, conflict);
67919
- undo.push(() => fs12.renameSync(conflict, src));
68117
+ fs13.renameSync(src, conflict);
68118
+ undo.push(() => fs13.renameSync(conflict, src));
67920
68119
  };
67921
68120
  try {
67922
68121
  for (const m2 of members) {
@@ -67942,7 +68141,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
67942
68141
  const generatedFiles = new Set(Array.isArray(generatedFile) ? generatedFile : [generatedFile]);
67943
68142
  const isGeneratedDraft = (name) => [...generatedFiles].some((g2) => name.startsWith(`.${g2}.`) && name.endsWith(".tmp"));
67944
68143
  try {
67945
- fs12.mkdirSync(overlay, { recursive: true });
68144
+ fs13.mkdirSync(overlay, { recursive: true });
67946
68145
  } catch {
67947
68146
  return false;
67948
68147
  }
@@ -67953,19 +68152,19 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
67953
68152
  );
67954
68153
  }
67955
68154
  try {
67956
- fs12.writeFileSync(overlayLockPath(overlay), `${process.pid}
68155
+ fs13.writeFileSync(overlayLockPath(overlay), `${process.pid}
67957
68156
  `);
67958
68157
  } catch {
67959
68158
  }
67960
68159
  const realEntries = /* @__PURE__ */ new Set();
67961
68160
  try {
67962
- for (const entry of fs12.readdirSync(realHome)) realEntries.add(entry);
68161
+ for (const entry of fs13.readdirSync(realHome)) realEntries.add(entry);
67963
68162
  } catch {
67964
68163
  }
67965
68164
  try {
67966
68165
  let overlayEntries;
67967
68166
  try {
67968
- overlayEntries = fs12.readdirSync(overlay);
68167
+ overlayEntries = fs13.readdirSync(overlay);
67969
68168
  } catch {
67970
68169
  overlayEntries = [];
67971
68170
  }
@@ -67976,7 +68175,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
67976
68175
  if (!members.some((m2) => m2 !== entry && overlayEntries.includes(m2))) continue;
67977
68176
  let mainSt;
67978
68177
  try {
67979
- mainSt = fs12.lstatSync(path18.join(overlay, entry));
68178
+ mainSt = fs13.lstatSync(path18.join(overlay, entry));
67980
68179
  } catch {
67981
68180
  }
67982
68181
  const keepSidecars = mainSt !== void 0 && isWriteThroughHardlink(path18.join(overlay, entry), path18.join(realHome, entry), mainSt);
@@ -67993,7 +68192,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
67993
68192
  const overlayPath = path18.join(overlay, entry);
67994
68193
  if (isGeneratedDraft(entry)) {
67995
68194
  try {
67996
- fs12.unlinkSync(overlayPath);
68195
+ fs13.unlinkSync(overlayPath);
67997
68196
  } catch {
67998
68197
  }
67999
68198
  continue;
@@ -68001,20 +68200,20 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
68001
68200
  if (skipEntries.has(entry)) continue;
68002
68201
  let st2;
68003
68202
  try {
68004
- st2 = fs12.lstatSync(overlayPath);
68203
+ st2 = fs13.lstatSync(overlayPath);
68005
68204
  } catch {
68006
68205
  continue;
68007
68206
  }
68008
68207
  if (st2.isSymbolicLink()) {
68009
68208
  let target;
68010
68209
  try {
68011
- target = fs12.readlinkSync(overlayPath);
68210
+ target = fs13.readlinkSync(overlayPath);
68012
68211
  } catch {
68013
68212
  }
68014
68213
  const wanted = realEntries.has(entry) ? path18.join(realHome, entry) : void 0;
68015
68214
  if (!wanted || target !== wanted) {
68016
68215
  try {
68017
- fs12.unlinkSync(overlayPath);
68216
+ fs13.unlinkSync(overlayPath);
68018
68217
  } catch {
68019
68218
  }
68020
68219
  }
@@ -68022,12 +68221,12 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
68022
68221
  const realPath = path18.join(realHome, entry);
68023
68222
  if (isWriteThroughHardlink(overlayPath, realPath, st2)) {
68024
68223
  try {
68025
- fs12.unlinkSync(overlayPath);
68224
+ fs13.unlinkSync(overlayPath);
68026
68225
  } catch {
68027
68226
  }
68028
68227
  } else if (mergeOverlayEntry(overlayPath, realPath, generatedFiles)) {
68029
68228
  try {
68030
- fs12.rmSync(overlayPath, { recursive: true, force: true });
68229
+ fs13.rmSync(overlayPath, { recursive: true, force: true });
68031
68230
  } catch {
68032
68231
  }
68033
68232
  } else {
@@ -68052,7 +68251,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
68052
68251
  const overlayPath = path18.join(overlay, entry);
68053
68252
  let present = false;
68054
68253
  try {
68055
- fs12.lstatSync(overlayPath);
68254
+ fs13.lstatSync(overlayPath);
68056
68255
  present = true;
68057
68256
  } catch {
68058
68257
  }
@@ -68084,32 +68283,32 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
68084
68283
  function mergeOverlayEntry(src, dst, excludedNames) {
68085
68284
  let st2;
68086
68285
  try {
68087
- st2 = fs12.lstatSync(src);
68286
+ st2 = fs13.lstatSync(src);
68088
68287
  } catch {
68089
68288
  return true;
68090
68289
  }
68091
68290
  let dstStat;
68092
68291
  try {
68093
- dstStat = fs12.lstatSync(dst);
68292
+ dstStat = fs13.lstatSync(dst);
68094
68293
  } catch {
68095
68294
  }
68096
68295
  if (st2.isDirectory()) {
68097
68296
  if (dstStat && !dstStat.isDirectory()) {
68098
68297
  try {
68099
- fs12.renameSync(dst, freeConflictName(dst));
68298
+ fs13.renameSync(dst, freeConflictName(dst));
68100
68299
  dstStat = void 0;
68101
68300
  } catch {
68102
68301
  return false;
68103
68302
  }
68104
68303
  }
68105
68304
  try {
68106
- fs12.mkdirSync(dst, { recursive: true });
68305
+ fs13.mkdirSync(dst, { recursive: true });
68107
68306
  } catch {
68108
68307
  return false;
68109
68308
  }
68110
68309
  let entries;
68111
68310
  try {
68112
- entries = fs12.readdirSync(src);
68311
+ entries = fs13.readdirSync(src);
68113
68312
  } catch {
68114
68313
  return false;
68115
68314
  }
@@ -68122,7 +68321,7 @@ function mergeOverlayEntry(src, dst, excludedNames) {
68122
68321
  }
68123
68322
  if (dstStat && dstStat.isDirectory()) {
68124
68323
  try {
68125
- fs12.renameSync(src, freeConflictName(dst));
68324
+ fs13.renameSync(src, freeConflictName(dst));
68126
68325
  return true;
68127
68326
  } catch {
68128
68327
  return false;
@@ -68131,13 +68330,13 @@ function mergeOverlayEntry(src, dst, excludedNames) {
68131
68330
  if (st2.isSymbolicLink()) {
68132
68331
  if (dstStat) {
68133
68332
  try {
68134
- fs12.unlinkSync(src);
68333
+ fs13.unlinkSync(src);
68135
68334
  } catch {
68136
68335
  }
68137
68336
  return true;
68138
68337
  }
68139
68338
  try {
68140
- fs12.renameSync(src, dst);
68339
+ fs13.renameSync(src, dst);
68141
68340
  } catch {
68142
68341
  return false;
68143
68342
  }
@@ -68145,7 +68344,7 @@ function mergeOverlayEntry(src, dst, excludedNames) {
68145
68344
  }
68146
68345
  if (dstStat && dstStat.mtimeMs >= st2.mtimeMs) {
68147
68346
  try {
68148
- fs12.renameSync(src, freeConflictName(dst));
68347
+ fs13.renameSync(src, freeConflictName(dst));
68149
68348
  return true;
68150
68349
  } catch {
68151
68350
  return false;
@@ -68153,13 +68352,13 @@ function mergeOverlayEntry(src, dst, excludedNames) {
68153
68352
  }
68154
68353
  if (dstStat) {
68155
68354
  try {
68156
- fs12.renameSync(dst, freeConflictName(dst));
68355
+ fs13.renameSync(dst, freeConflictName(dst));
68157
68356
  } catch {
68158
68357
  return false;
68159
68358
  }
68160
68359
  }
68161
68360
  try {
68162
- fs12.renameSync(src, dst);
68361
+ fs13.renameSync(src, dst);
68163
68362
  return true;
68164
68363
  } catch {
68165
68364
  return false;
@@ -68169,7 +68368,7 @@ function piPluginInstalled(piHome) {
68169
68368
  const root = selfPackageRoot();
68170
68369
  if (!root) return false;
68171
68370
  try {
68172
- const parsed = JSON.parse(fs12.readFileSync(path18.join(piHome, "settings.json"), "utf8"));
68371
+ const parsed = JSON.parse(fs13.readFileSync(path18.join(piHome, "settings.json"), "utf8"));
68173
68372
  const list = Array.isArray(parsed.packages) ? parsed.packages.map(String) : [];
68174
68373
  return list.some((p2) => isBiliPiEntry(p2, root));
68175
68374
  } catch {
@@ -68179,11 +68378,11 @@ function piPluginInstalled(piHome) {
68179
68378
  function writeOverlayFileAtomic(overlay, fileName, contents) {
68180
68379
  const draft = path18.join(overlay, `.${fileName}.${process.pid}.tmp`);
68181
68380
  try {
68182
- fs12.writeFileSync(draft, contents);
68183
- fs12.renameSync(draft, path18.join(overlay, fileName));
68381
+ fs13.writeFileSync(draft, contents);
68382
+ fs13.renameSync(draft, path18.join(overlay, fileName));
68184
68383
  } catch {
68185
68384
  try {
68186
- fs12.rmSync(draft, { force: true });
68385
+ fs13.rmSync(draft, { force: true });
68187
68386
  } catch {
68188
68387
  }
68189
68388
  }
@@ -68192,7 +68391,7 @@ function prepareDshHome(dshHome, origin, rewrites) {
68192
68391
  const cfgPath = path18.join(dshHome, "settings.yaml");
68193
68392
  let txt;
68194
68393
  try {
68195
- txt = fs12.readFileSync(cfgPath, "utf8");
68394
+ txt = fs13.readFileSync(cfgPath, "utf8");
68196
68395
  } catch {
68197
68396
  return void 0;
68198
68397
  }
@@ -68241,7 +68440,7 @@ env = { BILI_MCP_PROXY = ${JSON.stringify(origin)}, BILI_CONVERSATION_ID = ${JSO
68241
68440
  function prepareCodexHome(codexHome, origin, conversationId2) {
68242
68441
  let txt = "";
68243
68442
  try {
68244
- txt = fs12.readFileSync(path18.join(codexHome, "config.toml"), "utf8");
68443
+ txt = fs13.readFileSync(path18.join(codexHome, "config.toml"), "utf8");
68245
68444
  } catch {
68246
68445
  }
68247
68446
  const overlay = `${codexHome}-bili`;
@@ -68253,7 +68452,7 @@ function writeDshAcpPatch(dshHome) {
68253
68452
  const pluginUrl = pathToFileURL(selfDistFile("agent/dsh-acp.js")).href;
68254
68453
  const dir = `${dshHome}-bili`;
68255
68454
  try {
68256
- fs12.mkdirSync(dir, { recursive: true });
68455
+ fs13.mkdirSync(dir, { recursive: true });
68257
68456
  } catch {
68258
68457
  return void 0;
68259
68458
  }
@@ -68262,7 +68461,7 @@ function writeDshAcpPatch(dshHome) {
68262
68461
  `);
68263
68462
  const file = path18.join(dir, ".bili-acp.patch.yml");
68264
68463
  try {
68265
- return fs12.existsSync(file) ? file : void 0;
68464
+ return fs13.existsSync(file) ? file : void 0;
68266
68465
  } catch {
68267
68466
  return void 0;
68268
68467
  }
@@ -68277,7 +68476,7 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
68277
68476
  if (httpRewrites.length === 0 && httpsRewrites.length === 0 && !pluginPath) return void 0;
68278
68477
  let root = {};
68279
68478
  try {
68280
- const txt = fs12.readFileSync(configFile2, "utf8");
68479
+ const txt = fs13.readFileSync(configFile2, "utf8");
68281
68480
  const parsed = JSON.parse(txt);
68282
68481
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
68283
68482
  root = { ...parsed };
@@ -68305,9 +68504,9 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
68305
68504
  if (!plugins.includes(pluginPath)) plugins.push(pluginPath);
68306
68505
  root.plugin = plugins;
68307
68506
  }
68308
- const tmp = fs12.mkdtempSync(path18.join(os5.tmpdir(), "bili-opencode-"));
68507
+ const tmp = fs13.mkdtempSync(path18.join(os5.tmpdir(), "bili-opencode-"));
68309
68508
  const tmpFile = path18.join(tmp, "opencode.json");
68310
- fs12.writeFileSync(tmpFile, JSON.stringify(root));
68509
+ fs13.writeFileSync(tmpFile, JSON.stringify(root));
68311
68510
  return tmpFile;
68312
68511
  }
68313
68512
  function dedupeInOrder(list) {
@@ -68453,7 +68652,7 @@ async function ensureProxyRunning(opts, deps = {}) {
68453
68652
  const script = process.argv[1];
68454
68653
  if (!script) throw new Error("bili: cannot resolve launcher script path");
68455
68654
  const logPath2 = path18.join(os5.tmpdir(), `bili-proxy-${port}.log`);
68456
- const logFd = fs12.openSync(logPath2, "a");
68655
+ const logFd = fs13.openSync(logPath2, "a");
68457
68656
  const claimMarker = () => claimStartingMarker({ token: launchToken, pid: process.pid, host: opts.host, port, startedAt: now() });
68458
68657
  let claimed = claimMarker();
68459
68658
  if (!claimed) {
@@ -68487,7 +68686,7 @@ async function ensureProxyRunning(opts, deps = {}) {
68487
68686
  );
68488
68687
  } finally {
68489
68688
  try {
68490
- fs12.closeSync(logFd);
68689
+ fs13.closeSync(logFd);
68491
68690
  } catch {
68492
68691
  }
68493
68692
  }
@@ -68587,7 +68786,7 @@ function resolveOnPath(name, env) {
68587
68786
  for (const ext of PATH_EXTS) {
68588
68787
  const f2 = path18.join(dir, name + ext);
68589
68788
  try {
68590
- if (fs12.existsSync(f2) && fs12.statSync(f2).isFile()) return f2;
68789
+ if (fs13.existsSync(f2) && fs13.statSync(f2).isFile()) return f2;
68591
68790
  } catch {
68592
68791
  }
68593
68792
  }
@@ -68653,7 +68852,7 @@ async function runLaunch(params, deps = {}) {
68653
68852
  const ompRealHome = resolveOmpHome({ ...process.env, PI_CODING_AGENT_DIR: void 0 });
68654
68853
  if (base === "pi" && (routes.httpRewrites.length > 0 || routes.httpsRewrites.length > 0)) {
68655
68854
  const piExt = selfDistFile("agent/pi.js");
68656
- const extAvailable = piExt !== void 0 && fs12.existsSync(piExt) || piPluginInstalled(piRealHome);
68855
+ const extAvailable = piExt !== void 0 && fs13.existsSync(piExt) || piPluginInstalled(piRealHome);
68657
68856
  if (!extAvailable) {
68658
68857
  throw new Error(
68659
68858
  "bili: pi needs provider URL rewrites but the bili extension cannot load (dist/agent/pi.js missing and the plugin is not installed in ~/.pi/agent/settings.json) \u2014 reinstall billion-context or run `bili plugin install pi`"
@@ -68662,7 +68861,7 @@ async function runLaunch(params, deps = {}) {
68662
68861
  }
68663
68862
  if (base === "omp" && routes.httpRewrites.length > 0) {
68664
68863
  const ompExt = selfDistFile("agent/omp.js");
68665
- const extAvailable = ompExt !== void 0 && fs12.existsSync(ompExt) || ompPluginLoadedFrom(ompRealHome);
68864
+ const extAvailable = ompExt !== void 0 && fs13.existsSync(ompExt) || ompPluginLoadedFrom(ompRealHome);
68666
68865
  if (!extAvailable) {
68667
68866
  throw new Error(
68668
68867
  "bili: omp needs provider URL rewrites but the bili extension cannot load (dist/agent/omp.js missing and the plugin is not installed in ~/.omp/agent/config.yml) \u2014 reinstall billion-context or run `bili plugin install omp`"
@@ -68716,20 +68915,20 @@ async function runLaunch(params, deps = {}) {
68716
68915
  env = buildPiEnv(origin, ca, process.env, routes.httpRewrites, routes.httpsRewrites);
68717
68916
  delete env.PI_CODING_AGENT_DIR;
68718
68917
  const piExt = selfDistFile("agent/pi.js");
68719
- if (piExt && fs12.existsSync(piExt) && !piPluginInstalled(piRealHome)) {
68918
+ if (piExt && fs13.existsSync(piExt) && !piPluginInstalled(piRealHome)) {
68720
68919
  clientArgs = ["-e", piExt, ...clientArgs];
68721
68920
  }
68722
68921
  } else if (base === "omp") {
68723
68922
  env = buildPiEnv(origin, ca, process.env, routes.httpRewrites);
68724
68923
  delete env.PI_CODING_AGENT_DIR;
68725
68924
  const ompExt = selfDistFile("agent/omp.js");
68726
- if (ompExt && fs12.existsSync(ompExt) && !ompPluginLoadedFrom(ompRealHome)) {
68925
+ if (ompExt && fs13.existsSync(ompExt) && !ompPluginLoadedFrom(ompRealHome)) {
68727
68926
  clientArgs = ["-e", ompExt, ...clientArgs];
68728
68927
  }
68729
68928
  } else if (base === "opencode") {
68730
68929
  env = { ...process.env, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: ca, BILLION_CONTEXT_PROXY: origin };
68731
68930
  const opencodePlugin = selfDistFile("agent/opencode.js");
68732
- const opencodePluginPath = opencodePlugin && fs12.existsSync(opencodePlugin) ? opencodePlugin : void 0;
68931
+ const opencodePluginPath = opencodePlugin && fs13.existsSync(opencodePlugin) ? opencodePlugin : void 0;
68733
68932
  opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
68734
68933
  if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
68735
68934
  } else if (base === "hermes") {
@@ -68866,7 +69065,7 @@ async function runLaunch(params, deps = {}) {
68866
69065
  }
68867
69066
  if (injectMcp) {
68868
69067
  const mcpFile = path18.join(os5.tmpdir(), `bili-mcp-${Date.now()}.json`);
68869
- fs12.writeFileSync(mcpFile, JSON.stringify(buildMcpConfig(origin)));
69068
+ fs13.writeFileSync(mcpFile, JSON.stringify(buildMcpConfig(origin)));
68870
69069
  tmpFiles.push(mcpFile);
68871
69070
  clientArgs = ["--mcp-config", mcpFile, ...clientArgs];
68872
69071
  }
@@ -68885,13 +69084,13 @@ async function runLaunch(params, deps = {}) {
68885
69084
  stopProxy(handle2);
68886
69085
  if (opencodeTmpFile) {
68887
69086
  try {
68888
- fs12.rmSync(path18.dirname(opencodeTmpFile), { recursive: true, force: true });
69087
+ fs13.rmSync(path18.dirname(opencodeTmpFile), { recursive: true, force: true });
68889
69088
  } catch {
68890
69089
  }
68891
69090
  }
68892
69091
  for (const f2 of tmpFiles) {
68893
69092
  try {
68894
- fs12.rmSync(f2, { force: true });
69093
+ fs13.rmSync(f2, { force: true });
68895
69094
  } catch {
68896
69095
  }
68897
69096
  }
@@ -68918,7 +69117,7 @@ async function runTestPi(params, deps = {}) {
68918
69117
  const ca = resolveCaCertPath(process.env);
68919
69118
  const env = buildPiEnv(handle2.origin, ca, process.env);
68920
69119
  const sessionDir = path18.join(os5.tmpdir(), `bili-pi-test-${Date.now()}`);
68921
- fs12.mkdirSync(sessionDir, { recursive: true });
69120
+ fs13.mkdirSync(sessionDir, { recursive: true });
68922
69121
  const args = [
68923
69122
  "-p",
68924
69123
  "--no-session",