github-router 0.3.178 → 0.3.204

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.
@@ -1,6 +1,6 @@
1
- import { t as PATHS } from "./paths-BZPgxKUl.js";
2
- import { d as runCommandCapture, l as parseBoolEnv, n as isPidAlive, o as trackChild, p as runManagedExeCapture, r as registerColbertExitHandlers, t as getColbertInstanceUuid, u as resolveExecutable } from "./lifecycle-DrDEjx_c.js";
3
- import { i as registerExitHandlers, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-Dvr3pGGG.js";
1
+ import { t as PATHS } from "./paths-BO22pMUb.js";
2
+ import { d as runCommandCapture, l as parseBoolEnv, n as isPidAlive, o as trackChild, p as runManagedExeCapture, r as registerColbertExitHandlers, t as getColbertInstanceUuid, u as resolveExecutable } from "./lifecycle-D-1CYr1Y.js";
3
+ import { i as registerExitHandlers, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-bPdiXjYB.js";
4
4
  import { createRequire } from "node:module";
5
5
  import consola from "consola";
6
6
  import { createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
@@ -623,6 +623,13 @@ function normalizeModelId$1(id) {
623
623
  * version pinning (a dated catalog id matched at Step 1) always wins.
624
624
  * 6. Return as-is with a warning
625
625
  */
626
+ /**
627
+ * `[1m]`-downgrade warnings we've already emitted this process. `resolveModel`
628
+ * is called many times per launch (env setup, model validation, the banner,
629
+ * and — under `serve` — on every model-picker `/models` poll), so the downgrade
630
+ * notice is deduped to once per model id to avoid log spam.
631
+ */
632
+ const warnedOneMDowngrade = /* @__PURE__ */ new Set();
626
633
  function resolveModel(modelId) {
627
634
  const models = state.models?.data;
628
635
  if (!models) return modelId;
@@ -630,7 +637,10 @@ function resolveModel(modelId) {
630
637
  if (oneMMatch) {
631
638
  const stripped = oneMMatch[1];
632
639
  const resolved = resolveModel(stripped);
633
- if (!/-1m(?:$|-)/.test(resolved)) consola.warn(`Model "${modelId}" requested 1M context but no -1m backend is in Copilot's catalog for this tier/family; downgrading upstream to "${resolved}" (200K). Claude Code's local context accounting will still assume 1M — expect premature auto-compact. Drop the [1m] suffix (or unset CLAUDE_CODE_DISABLE_1M_CONTEXT if you set it) to silence.`);
640
+ if (!/-1m(?:$|-)/.test(resolved) && !warnedOneMDowngrade.has(modelId)) {
641
+ warnedOneMDowngrade.add(modelId);
642
+ consola.warn(`Model "${modelId}" requested 1M context but no -1m backend is in Copilot's catalog for this tier/family; downgrading upstream to "${resolved}" (200K). Claude Code's local context accounting will still assume 1M — expect premature auto-compact. Drop the [1m] suffix (or unset CLAUDE_CODE_DISABLE_1M_CONTEXT if you set it) to silence.`);
643
+ }
634
644
  return resolved;
635
645
  }
636
646
  if (models.some((m) => m.id === modelId)) return modelId;
@@ -1145,6 +1155,25 @@ function collapsePathKeys(env) {
1145
1155
  return env;
1146
1156
  }
1147
1157
 
1158
+ //#endregion
1159
+ //#region src/lib/mcp-workspace-header.ts
1160
+ /** Header the per-session MCP headersHelper emits, carrying the calling Claude
1161
+ * session's working directory. The /mcp handler uses it as the default
1162
+ * `workspace` for repo-scoped tools so a machine-wide `serve` targets the
1163
+ * active repo, not the proxy launch cwd. */
1164
+ const MCP_WORKSPACE_HEADER = "X-GH-Workspace";
1165
+ /** stdout JSON the headersHelper prints; Claude merges it into the connection
1166
+ * headers. `cwd` is the helper's own process cwd = the session's project dir. */
1167
+ function buildWorkspaceHeaderJson(cwd) {
1168
+ return JSON.stringify({ [MCP_WORKSPACE_HEADER]: cwd });
1169
+ }
1170
+ /** Command string Claude runs as the headersHelper. Mirrors
1171
+ * buildPromptSubmitHookCommand's quoting (src/lib/orchestration/prompt-submit-hook.ts). */
1172
+ function buildWorkspaceHeaderHelperCommand(execPath, scriptPath) {
1173
+ const q = (s) => `"${s}"`;
1174
+ return scriptPath && scriptPath !== execPath ? `${q(execPath)} ${q(scriptPath)} internal-workspace-header` : `${q(execPath)} internal-workspace-header`;
1175
+ }
1176
+
1148
1177
  //#endregion
1149
1178
  //#region src/lib/insecure-tls.ts
1150
1179
  const IS_BUN$1 = typeof globalThis.Bun !== "undefined";
@@ -1338,7 +1367,7 @@ var ArtifactClient = class {
1338
1367
  attempt += 1;
1339
1368
  if (!(err instanceof ArtifactError && err.retryable && retryableCodes.has(err.code)) || attempt > retries || signal?.aborted) throw err;
1340
1369
  const base = this.retryBaseMs;
1341
- await sleep$2(base <= 0 ? 0 : Math.round(base * 2 ** (attempt - 1) * (.5 + Math.random() * .5)), signal);
1370
+ await sleep$3(base <= 0 ? 0 : Math.round(base * 2 ** (attempt - 1) * (.5 + Math.random() * .5)), signal);
1342
1371
  }
1343
1372
  }
1344
1373
  async requestOnce(o) {
@@ -1402,7 +1431,7 @@ var ArtifactClient = class {
1402
1431
  }
1403
1432
  }
1404
1433
  };
1405
- function sleep$2(ms, signal) {
1434
+ function sleep$3(ms, signal) {
1406
1435
  if (ms <= 0) return Promise.resolve();
1407
1436
  return new Promise((resolve, reject) => {
1408
1437
  const onAbort = () => {
@@ -3104,7 +3133,7 @@ function isHardNotReady(reason) {
3104
3133
  */
3105
3134
  async function waitForMessageReady(client, localId, options = {}) {
3106
3135
  const now = options.now ?? Date.now;
3107
- const sleep$3 = options.sleep ?? realSleep;
3136
+ const sleep$4 = options.sleep ?? realSleep;
3108
3137
  const waitMs = Math.max(0, options.waitMs ?? 0);
3109
3138
  const pollMs = Math.max(1, options.pollMs ?? DEFAULT_READY_POLL_MS);
3110
3139
  const deadline = now() + waitMs;
@@ -3136,7 +3165,7 @@ async function waitForMessageReady(client, localId, options = {}) {
3136
3165
  ready: false,
3137
3166
  readiness: last
3138
3167
  };
3139
- await sleep$3(Math.min(pollMs, remaining));
3168
+ await sleep$4(Math.min(pollMs, remaining));
3140
3169
  }
3141
3170
  }
3142
3171
  /**
@@ -3214,7 +3243,7 @@ async function primeTurnCursor(client, localId, timeoutMs, signal) {
3214
3243
  */
3215
3244
  async function waitForTurnSettled(client, localId, options) {
3216
3245
  const now = options.now ?? Date.now;
3217
- const sleep$3 = options.sleep ?? realSleep;
3246
+ const sleep$4 = options.sleep ?? realSleep;
3218
3247
  const pollTimeoutMs = Math.max(1, options.pollTimeoutMs ?? DEFAULT_TURN_POLL_MS);
3219
3248
  const budget = Number.isFinite(options.timeoutMs) ? Math.max(0, options.timeoutMs) : 0;
3220
3249
  const deadline = now() + budget;
@@ -3246,7 +3275,7 @@ async function waitForTurnSettled(client, localId, options) {
3246
3275
  reason: "timeout",
3247
3276
  cursor
3248
3277
  };
3249
- await sleep$3(Math.min(TURN_POLL_ERROR_BACKOFF_MS, Math.max(0, deadline - now())));
3278
+ await sleep$4(Math.min(TURN_POLL_ERROR_BACKOFF_MS, Math.max(0, deadline - now())));
3250
3279
  continue;
3251
3280
  }
3252
3281
  cursor = response.cursor;
@@ -3363,13 +3392,13 @@ async function readTail(client, localId, lines, signal) {
3363
3392
  async function driveTask(deps) {
3364
3393
  const { client, localId, prompt, timeoutMs, expectReport, idempotencyKey, interruptKey, reportId, signal } = deps;
3365
3394
  const now = deps.now ?? Date.now;
3366
- const sleep$3 = deps.sleep ?? realSleep;
3395
+ const sleep$4 = deps.sleep ?? realSleep;
3367
3396
  const tailLines = deps.tailLines ?? DEFAULT_TAIL_LINES;
3368
3397
  const pollTimeoutMs = deps.pollTimeoutMs;
3369
3398
  const readyResult = await waitForMessageReady(client, localId, {
3370
3399
  waitMs: deps.idleWaitMs ?? DEFAULT_IDLE_WAIT_MS,
3371
3400
  now,
3372
- sleep: sleep$3,
3401
+ sleep: sleep$4,
3373
3402
  signal
3374
3403
  });
3375
3404
  if (!readyResult.ready && isHardNotReady(readyResult.readiness.reason)) return {
@@ -3412,7 +3441,7 @@ async function driveTask(deps) {
3412
3441
  pollTimeoutMs,
3413
3442
  cursor,
3414
3443
  now,
3415
- sleep: sleep$3,
3444
+ sleep: sleep$4,
3416
3445
  signal
3417
3446
  });
3418
3447
  cursor = settle.cursor;
@@ -3434,7 +3463,7 @@ async function driveTask(deps) {
3434
3463
  pollTimeoutMs,
3435
3464
  cursor,
3436
3465
  now,
3437
- sleep: sleep$3,
3466
+ sleep: sleep$4,
3438
3467
  signal
3439
3468
  });
3440
3469
  recovered = recovery.settled;
@@ -5703,7 +5732,7 @@ function runFenced(token, fn) {
5703
5732
  function currentFenceToken() {
5704
5733
  return fenceStore.getStore();
5705
5734
  }
5706
- function sleep$1(ms) {
5735
+ function sleep$2(ms) {
5707
5736
  return new Promise((resolve) => setTimeout(resolve, ms));
5708
5737
  }
5709
5738
  async function writeJsonSecure(target, value) {
@@ -5750,7 +5779,7 @@ async function withFileLock(target, fn) {
5750
5779
  }
5751
5780
  } catch {}
5752
5781
  if (Date.now() - start > LOCK_MAX_WAIT_MS) throw new Error(`first-mate durable-store lock timeout for ${target}`);
5753
- await sleep$1(LOCK_RETRY_MS);
5782
+ await sleep$2(LOCK_RETRY_MS);
5754
5783
  }
5755
5784
  const verifyOwner = async () => {
5756
5785
  try {
@@ -5829,7 +5858,7 @@ async function commitJsonCas(opts) {
5829
5858
  };
5830
5859
  if (explicit) throw new DurableConflictError(`durable store rev changed under CAS for ${opts.path} (expected ${base})`);
5831
5860
  lastConflict = new DurableConflictError(`durable store contention for ${opts.path} (attempt ${attempt + 1}/${OCC_MAX_ATTEMPTS})`);
5832
- await sleep$1(Math.floor(OCC_BACKOFF_MS * (attempt + 1) * (.5 + Math.random())));
5861
+ await sleep$2(Math.floor(OCC_BACKOFF_MS * (attempt + 1) * (.5 + Math.random())));
5833
5862
  }
5834
5863
  throw lastConflict ?? new DurableConflictError(`durable store failed to converge for ${opts.path}`);
5835
5864
  }
@@ -9927,6 +9956,40 @@ function segment(value) {
9927
9956
 
9928
9957
  //#endregion
9929
9958
  //#region src/lib/first-mate/scheduler/answer-inbox.ts
9959
+ const sleep$1 = (ms) => new Promise((r) => setTimeout(r, ms));
9960
+ /**
9961
+ * Windows sharing-violation codes. When two processes rename the SAME source
9962
+ * concurrently, POSIX gives the loser a clean `ENOENT` (source already gone),
9963
+ * but Windows can transiently surface `EPERM`/`EACCES`/`EBUSY` (the source is
9964
+ * momentarily locked by the peer's in-flight rename) before it resolves to
9965
+ * ENOENT. Treat these as retryable, not fatal.
9966
+ */
9967
+ const WIN_RENAME_TRANSIENT = new Set([
9968
+ "EPERM",
9969
+ "EACCES",
9970
+ "EBUSY"
9971
+ ]);
9972
+ /**
9973
+ * Atomically claim `from` by renaming it to the process-unique `to`.
9974
+ * Returns `true` if THIS caller won the claim, `false` if a peer already took it
9975
+ * (source gone). Retries transient Windows sharing violations so two concurrent
9976
+ * drainers converge to exactly one winner instead of one throwing. Non-transient
9977
+ * errors propagate.
9978
+ */
9979
+ async function claimByRename(from, to) {
9980
+ for (let attempt = 0;; attempt++) try {
9981
+ await fs.rename(from, to);
9982
+ return true;
9983
+ } catch (err) {
9984
+ const code = err.code;
9985
+ if (code === "ENOENT") return false;
9986
+ if (WIN_RENAME_TRANSIENT.has(code ?? "") && attempt < 25) {
9987
+ await sleep$1(4 + attempt);
9988
+ continue;
9989
+ }
9990
+ throw err;
9991
+ }
9992
+ }
9930
9993
  var AnswerInbox = class {
9931
9994
  file;
9932
9995
  chain = Promise.resolve();
@@ -10003,12 +10066,7 @@ var AnswerInbox = class {
10003
10066
  const orphan = nodePath.join(dir, name);
10004
10067
  if (this.inflight.has(orphan)) continue;
10005
10068
  const claim = `${orphan}.claim.${process.pid}.${randomBytes(4).toString("hex")}`;
10006
- try {
10007
- await fs.rename(orphan, claim);
10008
- } catch (err) {
10009
- if (err.code === "ENOENT") continue;
10010
- throw err;
10011
- }
10069
+ if (!await claimByRename(orphan, claim)) continue;
10012
10070
  try {
10013
10071
  this.mergeLines(await fs.readFile(claim, "utf8"), out);
10014
10072
  claimed.push(claim);
@@ -10017,12 +10075,11 @@ var AnswerInbox = class {
10017
10075
  }
10018
10076
  }
10019
10077
  const target = `${this.file}.draining.${process.pid}.${randomBytes(4).toString("hex")}`;
10020
- try {
10021
- await fs.rename(this.file, target);
10078
+ if (await claimByRename(this.file, target)) try {
10022
10079
  this.mergeLines(await fs.readFile(target, "utf8"), out);
10023
10080
  claimed.push(target);
10024
10081
  } catch (err) {
10025
- if (err.code !== "ENOENT") throw err;
10082
+ if (err.code !== "ENOENT") consola.warn(`first-mate: deferring unreadable inbox claim ${target} for retry:`, err);
10026
10083
  }
10027
10084
  for (const p of claimed) this.inflight.add(p);
10028
10085
  const ack = async () => {
@@ -15582,6 +15639,7 @@ async function provisionAndIndexColbert(opts = {}) {
15582
15639
  return;
15583
15640
  }
15584
15641
  if (!provisioned) return;
15642
+ if (opts.skipCwdIndex) return;
15585
15643
  const cwd = opts.cwd ?? process$1.cwd();
15586
15644
  try {
15587
15645
  if ((await gitState(cwd)).isRepo && await startupKickAllowed(cwd)) kickBackgroundInit(cwd);
@@ -16901,7 +16959,7 @@ function logAudit$1(record) {
16901
16959
  try {
16902
16960
  const fs$2 = await import("node:fs/promises");
16903
16961
  const path$1 = await import("node:path");
16904
- const { PATHS: PATHS$1 } = await import("./paths-CDYvyApX.js");
16962
+ const { PATHS: PATHS$1 } = await import("./paths-B5k78n0d.js");
16905
16963
  const dir = path$1.join(PATHS$1.APP_DIR, "browser-mcp");
16906
16964
  await fs$2.mkdir(dir, { recursive: true });
16907
16965
  const line = JSON.stringify({
@@ -24233,7 +24291,13 @@ function logTelemetry(t) {
24233
24291
  if (t.errorMessage) parts.push(`error=${JSON.stringify(t.errorMessage)}`);
24234
24292
  process.stderr.write(parts.join(" ") + "\n");
24235
24293
  }
24236
- async function handleToolsCall(body, scope) {
24294
+ function toolAcceptsWorkspace(tool$1) {
24295
+ return tool$1.capability === "worker" || tool$1.toolNameHttp === "code" || tool$1.toolNameHttp === "run_workflow";
24296
+ }
24297
+ function applySessionWorkspace(args, sessionWorkspace, tool$1) {
24298
+ if ((!tool$1 || toolAcceptsWorkspace(tool$1)) && typeof sessionWorkspace === "string" && sessionWorkspace.length > 0 && nodePath.isAbsolute(sessionWorkspace) && (args.workspace === void 0 || args.workspace === "")) args.workspace = sessionWorkspace;
24299
+ }
24300
+ async function handleToolsCall(body, scope, sessionWorkspace) {
24237
24301
  const params = body.params ?? {};
24238
24302
  const name = typeof params.name === "string" ? params.name : "";
24239
24303
  const args = params.arguments ?? {};
@@ -24296,6 +24360,7 @@ async function handleToolsCall(body, scope) {
24296
24360
  const telemetryName = persona ? persona.agentName : nonPersonaTool.toolNameHttp;
24297
24361
  const telemetryModel = persona ? persona.model : "(non-persona)";
24298
24362
  try {
24363
+ if (nonPersonaTool) applySessionWorkspace(args, sessionWorkspace, nonPersonaTool);
24299
24364
  const result = persona ? await callPersona(persona, personaPrompt, personaContext, personaEffort, aborter?.signal) : await nonPersonaTool.handler(args, aborter?.signal);
24300
24365
  logTelemetry({
24301
24366
  name: telemetryName,
@@ -24341,7 +24406,7 @@ function handleCancelledNotification(body) {
24341
24406
  }
24342
24407
  cancelInflight(requestId, "client requested cancellation");
24343
24408
  }
24344
- async function handleRpc(_c, body, scope) {
24409
+ async function handleRpc(_c, body, scope, sessionWorkspace) {
24345
24410
  if (body === null || typeof body !== "object" || Array.isArray(body)) return {
24346
24411
  status: 200,
24347
24412
  body: rpcError(null, RPC_INVALID_REQUEST, "jsonrpc 2.0 envelope required")
@@ -24392,7 +24457,7 @@ async function handleRpc(_c, body, scope) {
24392
24457
  };
24393
24458
  return {
24394
24459
  status: 200,
24395
- body: await handleToolsCall(body, scope)
24460
+ body: await handleToolsCall(body, scope, sessionWorkspace)
24396
24461
  };
24397
24462
  case "resources/list":
24398
24463
  if (isNotification) return {
@@ -24483,17 +24548,18 @@ async function handleMcpPost(c, scopeArg = "all") {
24483
24548
  consola.debug("/mcp parse error:", err);
24484
24549
  return c.json(rpcError(null, RPC_PARSE_ERROR, "request body is not valid JSON"), 200);
24485
24550
  }
24551
+ const sessionWorkspace = c.req.header(MCP_WORKSPACE_HEADER);
24486
24552
  if (process.env.GH_ROUTER_LOG_PEER_MCP === "1" && typeof body === "object" && body !== null && !Array.isArray(body) && body.method === "tools/call") {
24487
24553
  const nm = typeof body.params?.name === "string" ? body.params.name : "?";
24488
24554
  process.stderr.write(`[peer-mcp] recv t=${Date.now()} name=${nm} scope=${scope} inflight=${currentInFlight()}\n`);
24489
24555
  }
24490
- if (typeof body === "object" && body !== null && !Array.isArray(body) && body.method === "tools/call" && acceptsEventStream(c.req.header("accept"))) return handleToolsCallSSE(body, scope);
24556
+ if (typeof body === "object" && body !== null && !Array.isArray(body) && body.method === "tools/call" && acceptsEventStream(c.req.header("accept"))) return handleToolsCallSSE(body, scope, sessionWorkspace);
24491
24557
  if (typeof body === "object" && body !== null && !Array.isArray(body) && body.method === "tools/call") {
24492
24558
  const preflight = jsonPathPreflightCap(body, scope);
24493
24559
  if (preflight) return c.json(preflight, 200);
24494
24560
  }
24495
24561
  try {
24496
- const { status, body: respBody } = await handleRpc(c, body, scope);
24562
+ const { status, body: respBody } = await handleRpc(c, body, scope, sessionWorkspace);
24497
24563
  if (respBody === null) return c.body(null, status);
24498
24564
  return c.json(respBody, status);
24499
24565
  } catch (err) {
@@ -24546,9 +24612,9 @@ function acceptsEventStream(accept) {
24546
24612
  * "Invalid state: Controller is already closed" race without warning.
24547
24613
  */
24548
24614
  const SSE_HEARTBEAT_INTERVAL_MS = 5e3;
24549
- async function handleToolsCallSSE(body, scope) {
24615
+ async function handleToolsCallSSE(body, scope, sessionWorkspace) {
24550
24616
  const encoder = new TextEncoder();
24551
- const callPromise = handleToolsCall(body, scope);
24617
+ const callPromise = handleToolsCall(body, scope, sessionWorkspace);
24552
24618
  let heartbeatHandle;
24553
24619
  const stream = new ReadableStream({
24554
24620
  async start(controller) {
@@ -31459,8 +31525,9 @@ function assertMcpToolSurfaceConsistent() {
31459
31525
  /**
31460
31526
  * Shared closure body for the two worker MCP tools. Validates the
31461
31527
  * minimal arg shape (prompt required + optional knobs typed), then
31462
- * forwards to `runWorkerAgent`. `workspace` defaults to the proxy's
31463
- * launch cwd; callers can override via the optional `workspace` arg
31528
+ * forwards to `runWorkerAgent`. Outside serve mode, `workspace` defaults
31529
+ * to the proxy's launch cwd; serve mode requires an explicit/header-derived
31530
+ * workspace. Callers can override via the optional `workspace` arg
31464
31531
  * (absolute paths only — enforced here). The engine performs every
31465
31532
  * deeper validation (model existence, thinking clamp, worktree
31466
31533
  * provisioning, semaphore acquisition, workspace realpath +
@@ -31522,7 +31589,7 @@ async function runWorkerToolCall(call) {
31522
31589
  };
31523
31590
  worktree = args.worktree;
31524
31591
  }
31525
- let workspace = process.cwd();
31592
+ let workspace;
31526
31593
  if (args.workspace !== void 0) {
31527
31594
  if (typeof args.workspace !== "string" || args.workspace.length === 0) return {
31528
31595
  content: [{
@@ -31539,7 +31606,14 @@ async function runWorkerToolCall(call) {
31539
31606
  isError: true
31540
31607
  };
31541
31608
  workspace = args.workspace;
31542
- }
31609
+ } else if (state.serveMode) return {
31610
+ content: [{
31611
+ type: "text",
31612
+ text: `worker_${mode}: a workspace is required. This is a machine-wide github-router serve; pass the absolute path of the project you are working in as \`workspace\`.`
31613
+ }],
31614
+ isError: true
31615
+ };
31616
+ else workspace = process.cwd();
31543
31617
  let maxWallClockMs;
31544
31618
  let clampNote = "";
31545
31619
  if (args.maxWallClockMs !== void 0) {
@@ -31770,7 +31844,34 @@ async function runStandInToolCall(args, signal) {
31770
31844
  text: JSON.stringify(result)
31771
31845
  }] };
31772
31846
  }
31847
+ /**
31848
+ * Every exact `mcp__<key>__<tool>` name github-router injects, for the given
31849
+ * resolved group keys (`peers`/`search`/… → their collision-resolved mcpServers
31850
+ * key). A SUPERSET — it ignores per-tool capability gates because an allow-list
31851
+ * entry for a tool that isn't actually served is inert, which keeps it correct
31852
+ * as gates change and as tools are added.
31853
+ *
31854
+ * Used to seed CloudCLI's `localStorage['claude-settings'].allowedTools` so its
31855
+ * Agent-SDK `canUseTool` auto-approves our MCP tools in PLAN mode. `canUseTool`
31856
+ * does EXACT tool-name matching (no `mcp__<server>` wildcard — see
31857
+ * `matchesToolPermission` in CloudCLI's `claude-sdk.js`), so bare `mcp__peers`
31858
+ * would NOT cover `mcp__peers__gemini_critic`; the exact names are required.
31859
+ * This is the ONLY lever for plan mode: bypass mode skips `canUseTool`, and the
31860
+ * mirror `settings.json permissions.allow` is NOT consulted by `canUseTool`
31861
+ * (which reads `sdkOptions.allowedTools`, seeded from this localStorage key).
31862
+ */
31863
+ function enumerateInjectedMcpToolNames(groupKeys, opts = {}) {
31864
+ const names = [];
31865
+ const peersKey = groupKeys.peers;
31866
+ if (peersKey) for (const p of [...PERSONAS_READ, ...PERSONAS_WRITE]) names.push(`mcp__${peersKey}__${p.toolNameHttp}`);
31867
+ for (const t of NON_PERSONA_MCP_TOOLS) {
31868
+ const key = groupKeys[t.group];
31869
+ if (key) names.push(`mcp__${key}__${t.toolNameHttp}`);
31870
+ }
31871
+ if (opts.codexCli) names.push("mcp__codex-cli__codex");
31872
+ return [...new Set(names)];
31873
+ }
31773
31874
 
31774
31875
  //#endregion
31775
- export { isAdvisorRequested as $, cacheCopilotVersion as $t, liveExec as A, provisionBrowserAssets as At, withNoOutputRetry as B, DEFAULT_CODEX_MODEL as Bt, fileReviewDebounce as C, resolveMcpToolTimeoutMs as Ct, stopGateEnabledForRepo as D, MAX_RESPONSE_BODY_BYTES as Dt, repoRoot as E, createChatCompletions as Et, IMPLEMENT_DEFAULT_MODEL as F, shouldUseInsecureTls as Ft, vscodeRipgrepPath as G, generateRandomPort as Gt, buildToolbeltAwareness as H, DEFAULT_PORT as Ht, PLAN_DEFAULT_MODEL as I, ArtifactClient as It, searchWeb as J, withInstallLock as Jt, TOOLBELT_TOOLS$1 as K, pickClaudeDefault as Kt, REVIEW_DEFAULT_MODEL as L, collapsePathKeys as Lt, BROWSE_DEFAULT_MODEL as M, provisionAndIndexColbert as Mt, DEFAULT_MODEL as N, extractTarGzMember as Nt, stopReviewStateDir as O, readResponseBodyCapped as Ot, EXPLORE_DEFAULT_MODEL as P, extractZipMember as Pt, injectAdvisorTool as Q, tryRefreshAndRetry as Qt, appendPlanReminder as R, toolbeltPathOverride as Rt, fileLastPromptStore as S, assembleResponsesPayload as St, repoFingerprint as T, createResponses as Tt, toolbeltEnabled as U, UPSTREAM_FETCH_TIMEOUT_MS as Ut, availableToolCommands as V, DEFAULT_CODEX_MODEL_FALLBACKS as Vt, toolbeltSkipSet as W, UPSTREAM_INACTIVITY_TIMEOUT_MS as Wt, ADVISOR_TOOL_INSTRUCTIONS as X, setupGitHubAgentToken as Xt, ADVISOR_INTERNAL_TOOL_NAME as Y, setupCopilotToken as Yt, buildAdvisorStream as Z, setupGitHubToken as Zt, stopGateId as _, workerToolsEnabled as _t, buildPeerAwarenessSnippet as a, resolveModel as an, relayAnthropicStream as at, fileBaselineStore as b, createMessages as bt, buildArtifactOpenHookCommand as c, fetchWithTransientRetry as cn, agentToolsEnabled as ct, captureLaunchBaseline as d, GITHUB_API_BASE_URL as dn, browserCompoundToolsEnabled as dt, cacheModels as en, buildAnthropicErrorEvent as et, decideStopHook as f, copilotBaseUrl as fn, browserToolsEnabled as ft, stopGateDisabled as g, standInToolEnabled as gt, launchBaselineKey as h, state as hn, nativeSubagentModel as ht, buildAgentPrompt as i, resolveCodexModel as in, readIteratorWithTimeout as it, resolveSealedGate as j, hasSupportedBrowserInstalled as jt, trustRepo as k, parseJsonOrDiagnose as kt, buildSessionBindHookCommand as l, HTTPError as ln, artifactToolsEnabled as lt, injectStopHookIntoSettingsFile as m, githubHeaders as mn, geminiAvailable as mt, MCP_GROUPS as n, filterBetaHeader as nn, isControllerClosedError as nt, buildPeerAwarenessSummary as o, sleep as on, handleMcpDelete as ot, fileBlockBudget as p, copilotHeaders as pn, fleetToolsEnabled as pt, assetFor as q, getPackageVersion as qt, assertMcpToolSurfaceConsistent as r, isNullish as rn, logStreamError as rt, personasFor as s, getModels as sn, handleMcpPost as st, GROUP_META as t, cacheVSCodeVersion as tn, buildOpenAIErrorEvent as tt, buildStopHookCommand as u, forwardError as un, browseAgentEnabled as ut, stopGatePlanMode as v, shimDefaultsToXhigh as vt, isSubagentContext as w, pickEndpoint as wt, fileFindingsStore as x, getTokenCount as xt, stopReviewEnabled as y, countTokens as yt, runWorkerAgent as z, DEFAULT_CLAUDE_MODEL_FALLBACKS as zt };
31776
- //# sourceMappingURL=peer-mcp-personas-B1-1mVPB.js.map
31876
+ export { buildAdvisorStream as $, setupCopilotToken as $t, trustRepo as A, readResponseBodyCapped as At, runWorkerAgent as B, buildWorkspaceHeaderJson as Bt, fileLastPromptStore as C, getTokenCount as Ct, repoRoot as D, createResponses as Dt, repoFingerprint as E, pickEndpoint as Et, EXPLORE_DEFAULT_MODEL as F, extractTarGzMember as Ft, toolbeltEnabled as G, DEFAULT_CODEX_MODEL_FALLBACKS as Gt, buildEnv as H, toolbeltPathOverride as Ht, IMPLEMENT_DEFAULT_MODEL as I, extractZipMember as It, TOOLBELT_TOOLS$1 as J, UPSTREAM_INACTIVITY_TIMEOUT_MS as Jt, toolbeltSkipSet as K, DEFAULT_PORT as Kt, PLAN_DEFAULT_MODEL as L, shouldUseInsecureTls as Lt, resolveSealedGate as M, provisionBrowserAssets as Mt, BROWSE_DEFAULT_MODEL as N, hasSupportedBrowserInstalled as Nt, stopGateEnabledForRepo as O, createChatCompletions as Ot, DEFAULT_MODEL as P, provisionAndIndexColbert as Pt, ADVISOR_TOOL_INSTRUCTIONS as Q, withInstallLock as Qt, REVIEW_DEFAULT_MODEL as R, ArtifactClient as Rt, fileFindingsStore as S, createMessages as St, isSubagentContext as T, resolveMcpToolTimeoutMs as Tt, availableToolCommands as U, DEFAULT_CLAUDE_MODEL_FALLBACKS as Ut, withNoOutputRetry as V, collapsePathKeys as Vt, buildToolbeltAwareness as W, DEFAULT_CODEX_MODEL as Wt, searchWeb as X, pickClaudeDefault as Xt, assetFor as Y, generateRandomPort as Yt, ADVISOR_INTERNAL_TOOL_NAME as Z, getPackageVersion as Zt, stopGateDisabled as _, copilotBaseUrl as _n, nativeSubagentModel as _t, buildPeerAwarenessSnippet as a, cacheVSCodeVersion as an, logStreamError as at, stopReviewEnabled as b, state as bn, shimDefaultsToXhigh as bt, personasFor as c, resolveCodexModel as cn, handleMcpDelete as ct, buildStopHookCommand as d, getModels as dn, artifactToolsEnabled as dt, setupGitHubAgentToken as en, injectAdvisorTool as et, captureLaunchBaseline as f, getGitHubUser as fn, browseAgentEnabled as ft, launchBaselineKey as g, GITHUB_API_BASE_URL as gn, geminiAvailable as gt, injectStopHookIntoSettingsFile as h, forwardError as hn, fleetToolsEnabled as ht, buildAgentPrompt as i, cacheModels as in, isControllerClosedError as it, liveExec as j, parseJsonOrDiagnose as jt, stopReviewStateDir as k, MAX_RESPONSE_BODY_BYTES as kt, buildArtifactOpenHookCommand as l, resolveModel as ln, handleMcpPost as lt, fileBlockBudget as m, HTTPError as mn, browserToolsEnabled as mt, MCP_GROUPS as n, tryRefreshAndRetry as nn, buildAnthropicErrorEvent as nt, buildPeerAwarenessSummary as o, filterBetaHeader as on, readIteratorWithTimeout as ot, decideStopHook as p, fetchWithTransientRetry as pn, browserCompoundToolsEnabled as pt, vscodeRipgrepPath as q, UPSTREAM_FETCH_TIMEOUT_MS as qt, assertMcpToolSurfaceConsistent as r, cacheCopilotVersion as rn, buildOpenAIErrorEvent as rt, enumerateInjectedMcpToolNames as s, isNullish as sn, relayAnthropicStream as st, GROUP_META as t, setupGitHubToken as tn, isAdvisorRequested as tt, buildSessionBindHookCommand as u, sleep as un, agentToolsEnabled as ut, stopGateId as v, copilotHeaders as vn, standInToolEnabled as vt, fileReviewDebounce as w, assembleResponsesPayload as wt, fileBaselineStore as x, countTokens as xt, stopGatePlanMode as y, githubHeaders as yn, workerToolsEnabled as yt, appendPlanReminder as z, buildWorkspaceHeaderHelperCommand as zt };
31877
+ //# sourceMappingURL=peer-mcp-personas-BekOx3Rp.js.map