@atlasharness/atlascode 0.1.79 → 0.1.81

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.
Files changed (2) hide show
  1. package/dist/cli.js +937 -256
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -19862,7 +19862,7 @@ var init_openai = __esm(() => {
19862
19862
  });
19863
19863
 
19864
19864
  // src/modelprovider/constants.ts
19865
- var API_IMAGE_MAX_BASE64_SIZE, IMAGE_TARGET_RAW_SIZE, PDF_TARGET_RAW_SIZE, API_PDF_MAX_PAGES = 100, LLM_TIMEOUT_DEFAULT_MS = 900000, LLM_TIMEOUT_CAP_MS = 1800000, LLM_TIMEOUT_UNIT_WARN_THRESHOLD_MS = 60000, SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER, AFK_MODE_BETA_HEADER;
19865
+ var API_IMAGE_MAX_BASE64_SIZE, IMAGE_TARGET_RAW_SIZE, PDF_TARGET_RAW_SIZE, API_PDF_MAX_PAGES = 100, LLM_TIMEOUT_DEFAULT_MS = 900000, LLM_TIMEOUT_CAP_MS = 1800000, LLM_TIMEOUT_UNIT_WARN_THRESHOLD_MS = 60000, STREAM_IDLE_TIMEOUT_MS = 300000, STREAM_IDLE_RETURN_GRACE_MS = 1000, SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER, AFK_MODE_BETA_HEADER;
19866
19866
  var init_constants2 = __esm(() => {
19867
19867
  init_shared();
19868
19868
  API_IMAGE_MAX_BASE64_SIZE = 5 * 1024 * 1024;
@@ -19900,6 +19900,68 @@ var init_clients = __esm(() => {
19900
19900
  clientCache = new Map;
19901
19901
  });
19902
19902
 
19903
+ // src/modelprovider/streamIdleWatchdog.ts
19904
+ async function* withStreamIdleWatchdog(stream, timeoutMs = STREAM_IDLE_TIMEOUT_MS, returnGraceMs = STREAM_IDLE_RETURN_GRACE_MS) {
19905
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
19906
+ yield* stream;
19907
+ return;
19908
+ }
19909
+ const iterator = typeof stream[Symbol.asyncIterator] === "function" ? stream[Symbol.asyncIterator]() : async function* wrapSyncIterable() {
19910
+ yield* stream;
19911
+ }();
19912
+ try {
19913
+ while (true) {
19914
+ const nextPromise = iterator.next();
19915
+ nextPromise.catch(() => {});
19916
+ let timer;
19917
+ const timerPromise = new Promise((resolve) => {
19918
+ timer = setTimeout(() => resolve("timeout"), timeoutMs);
19919
+ if (typeof timer === "object" && timer !== null && "unref" in timer) {
19920
+ timer.unref();
19921
+ }
19922
+ });
19923
+ const winner = await Promise.race([nextPromise, timerPromise]);
19924
+ if (timer !== undefined)
19925
+ clearTimeout(timer);
19926
+ if (winner === "timeout") {
19927
+ throw new StreamIdleTimeoutError(timeoutMs);
19928
+ }
19929
+ const result = winner;
19930
+ if (result.done)
19931
+ return;
19932
+ yield result.value;
19933
+ }
19934
+ } finally {
19935
+ try {
19936
+ const ret = iterator.return?.();
19937
+ if (ret) {
19938
+ let graceTimer;
19939
+ const grace = new Promise((resolve) => {
19940
+ graceTimer = setTimeout(resolve, returnGraceMs);
19941
+ if (typeof graceTimer === "object" && graceTimer !== null && "unref" in graceTimer) {
19942
+ graceTimer.unref();
19943
+ }
19944
+ });
19945
+ await Promise.race([ret.then(() => {
19946
+ return;
19947
+ }, () => {}), grace]);
19948
+ }
19949
+ } catch {}
19950
+ }
19951
+ }
19952
+ var StreamIdleTimeoutError;
19953
+ var init_streamIdleWatchdog = __esm(() => {
19954
+ init_constants2();
19955
+ StreamIdleTimeoutError = class StreamIdleTimeoutError extends Error {
19956
+ timeoutMs;
19957
+ constructor(timeoutMs) {
19958
+ super(`Stream idle timeout: no chunk received for ${timeoutMs}ms`);
19959
+ this.name = "StreamIdleTimeoutError";
19960
+ this.timeoutMs = timeoutMs;
19961
+ }
19962
+ };
19963
+ });
19964
+
19903
19965
  // src/modelprovider/roles.ts
19904
19966
  function setEndpointConfigSource(source) {
19905
19967
  activeSource = source;
@@ -26560,6 +26622,46 @@ var init_schema = __esm(() => {
26560
26622
  cache = new WeakMap;
26561
26623
  });
26562
26624
 
26625
+ // src/modelprovider/capabilities.ts
26626
+ function stripProviderPrefix(model) {
26627
+ const idx = model.lastIndexOf("/");
26628
+ return idx >= 0 ? model.slice(idx + 1) : model;
26629
+ }
26630
+ function getModelMeta(modelId) {
26631
+ if (!modelId)
26632
+ return;
26633
+ const providers = getEndpointConfigSource().getProviders();
26634
+ for (const pCfg of Object.values(providers)) {
26635
+ const models = pCfg.models || [];
26636
+ const entry = models.find((m) => m?.id === modelId) ?? models.find((m) => m?.id === stripProviderPrefix(modelId));
26637
+ if (entry) {
26638
+ return {
26639
+ knowledgeCutoff: entry.knowledgeCutoff,
26640
+ supportsThinking: entry.supportsThinking,
26641
+ supportsEffort: entry.supportsEffort,
26642
+ supportsStructuredOutputs: entry.supportsStructuredOutputs,
26643
+ skipCyberMitigation: entry.skipCyberMitigation
26644
+ };
26645
+ }
26646
+ }
26647
+ return;
26648
+ }
26649
+ function getProviderContextWindow(modelId) {
26650
+ if (!modelId)
26651
+ return;
26652
+ const providers = getEndpointConfigSource().getProviders();
26653
+ for (const pCfg of Object.values(providers)) {
26654
+ const models = pCfg.models || [];
26655
+ const entry = models.find((m) => m?.id === modelId) ?? models.find((m) => m?.id === stripProviderPrefix(modelId));
26656
+ if (entry?.contextWindow)
26657
+ return entry.contextWindow;
26658
+ }
26659
+ return;
26660
+ }
26661
+ var init_capabilities = __esm(() => {
26662
+ init_roles7();
26663
+ });
26664
+
26563
26665
  // src/modelprovider/effort.ts
26564
26666
  function isEffortLevel(value) {
26565
26667
  return EFFORT_LEVELS.includes(value);
@@ -26625,6 +26727,13 @@ function lookupEffortByModel(model) {
26625
26727
  if (key.toLowerCase() === wanted)
26626
26728
  return level;
26627
26729
  }
26730
+ const base = stripProviderPrefix(model).toLowerCase();
26731
+ if (base !== wanted) {
26732
+ for (const [key, level] of Object.entries(map)) {
26733
+ if (key.toLowerCase() === base)
26734
+ return level;
26735
+ }
26736
+ }
26628
26737
  return;
26629
26738
  }
26630
26739
  function resolveAppliedEffort(model, appStateEffortValue) {
@@ -26638,6 +26747,7 @@ function resolveAppliedEffort(model, appStateEffortValue) {
26638
26747
  var effortByModelSource = null;
26639
26748
  var init_effort = __esm(() => {
26640
26749
  init_shared();
26750
+ init_capabilities();
26641
26751
  });
26642
26752
 
26643
26753
  // src/modelprovider/params.ts
@@ -26785,7 +26895,23 @@ async function buildOpenAITools(tools, options, emptyPermissionContext) {
26785
26895
  });
26786
26896
  }
26787
26897
  }
26788
- return out;
26898
+ return stableSortDedupeTools(out);
26899
+ }
26900
+ function stableSortDedupeTools(tools) {
26901
+ const nameOf = (t) => t.type === "function" ? t.function.name : t.custom.name;
26902
+ const sorted = [...tools].sort((a, b) => {
26903
+ const an = nameOf(a);
26904
+ const bn = nameOf(b);
26905
+ return an < bn ? -1 : an > bn ? 1 : 0;
26906
+ });
26907
+ const seen = new Set;
26908
+ return sorted.filter((t) => {
26909
+ const n = nameOf(t);
26910
+ if (seen.has(n))
26911
+ return false;
26912
+ seen.add(n);
26913
+ return true;
26914
+ });
26789
26915
  }
26790
26916
  function toResponseFormat(outputFormat) {
26791
26917
  if (!outputFormat)
@@ -27087,6 +27213,12 @@ function isQuotaExhaustedMessage(message) {
27087
27213
  }
27088
27214
  return false;
27089
27215
  }
27216
+ function parseToolSchemaRejectionError(err) {
27217
+ if (!(err instanceof APIError2) || err.status !== 400)
27218
+ return null;
27219
+ const m = /invalid schema for (?:tool|function) [`'"]?([A-Za-z0-9_.\-]+)[`'"]?/i.exec(err.message);
27220
+ return m ? m[1] : null;
27221
+ }
27090
27222
  function classifyAPIError(error) {
27091
27223
  if (error instanceof Error && error.message === "Request was aborted.") {
27092
27224
  return "aborted";
@@ -27227,6 +27359,8 @@ function shouldRetryModelError(err, signal) {
27227
27359
  return false;
27228
27360
  if (isClientRequestTimeout(err))
27229
27361
  return false;
27362
+ if (parseToolSchemaRejectionError(err))
27363
+ return false;
27230
27364
  return isRetryableError(err);
27231
27365
  }
27232
27366
  function llmTimeoutUnitHint(ms) {
@@ -27629,7 +27763,7 @@ class OpenAIProvider {
27629
27763
  let usage = null;
27630
27764
  let streamError = null;
27631
27765
  try {
27632
- for await (const chunk of stream) {
27766
+ for await (const chunk of withStreamIdleWatchdog(stream, STREAM_IDLE_TIMEOUT_MS)) {
27633
27767
  const choice = chunk.choices?.[0];
27634
27768
  const delta = choice?.delta;
27635
27769
  if (delta?.content) {
@@ -27887,6 +28021,8 @@ var init_modelprovider = __esm(() => {
27887
28021
  init_openai();
27888
28022
  init_clients();
27889
28023
  init_constants2();
28024
+ init_constants2();
28025
+ init_streamIdleWatchdog();
27890
28026
  init_roles7();
27891
28027
  init_shared();
27892
28028
  init_shared();
@@ -27912,42 +28048,6 @@ Fix: ${fix}`);
27912
28048
  };
27913
28049
  });
27914
28050
 
27915
- // src/modelprovider/capabilities.ts
27916
- function getModelMeta(modelId) {
27917
- if (!modelId)
27918
- return;
27919
- const providers = getEndpointConfigSource().getProviders();
27920
- for (const pCfg of Object.values(providers)) {
27921
- const models = pCfg.models || [];
27922
- const entry = models.find((m) => m?.id === modelId);
27923
- if (entry) {
27924
- return {
27925
- knowledgeCutoff: entry.knowledgeCutoff,
27926
- supportsThinking: entry.supportsThinking,
27927
- supportsEffort: entry.supportsEffort,
27928
- supportsStructuredOutputs: entry.supportsStructuredOutputs,
27929
- skipCyberMitigation: entry.skipCyberMitigation
27930
- };
27931
- }
27932
- }
27933
- return;
27934
- }
27935
- function getProviderContextWindow(modelId) {
27936
- if (!modelId)
27937
- return;
27938
- const providers = getEndpointConfigSource().getProviders();
27939
- for (const pCfg of Object.values(providers)) {
27940
- const models = pCfg.models || [];
27941
- const entry = models.find((m) => m?.id === modelId);
27942
- if (entry?.contextWindow)
27943
- return entry.contextWindow;
27944
- }
27945
- return;
27946
- }
27947
- var init_capabilities = __esm(() => {
27948
- init_roles7();
27949
- });
27950
-
27951
28051
  // src/modelprovider/roleFallbackStore.ts
27952
28052
  function clearRoleFallback() {
27953
28053
  lastRoleFallback = null;
@@ -28065,6 +28165,7 @@ var init_modelprovider2 = __esm(() => {
28065
28165
  init_roles7();
28066
28166
  init_modelprovider();
28067
28167
  init_constants2();
28168
+ init_streamIdleWatchdog();
28068
28169
  init_modelprovider();
28069
28170
  init_types2();
28070
28171
  init_modelErrors();
@@ -29428,8 +29529,8 @@ var SettingsSchema = () => object({
29428
29529
  mcpServers: record(string2(), any()).optional(),
29429
29530
  allowedMcpServers: any().optional(),
29430
29531
  deniedMcpServers: any().optional(),
29431
- enabledMcpjsonServers: array(string2()).optional(),
29432
- disabledMcpjsonServers: array(string2()).optional(),
29532
+ enabledMcpjsonServers: union([string2(), array(string2())]).transform((v) => Array.isArray(v) ? v : [v]).optional(),
29533
+ disabledMcpjsonServers: union([string2(), array(string2())]).transform((v) => Array.isArray(v) ? v : [v]).optional(),
29433
29534
  sandbox: any().optional(),
29434
29535
  permissions: any().optional(),
29435
29536
  hooks: lazy(() => HooksSchema).optional(),
@@ -29444,6 +29545,7 @@ var SettingsSchema = () => object({
29444
29545
  skipWebFetchPreflight: boolean2().optional(),
29445
29546
  search: object({ tavilyApiKey: string2().optional() }).optional(),
29446
29547
  tui: object({ fullscreen: boolean2().optional() }).optional(),
29548
+ idleCompaction: boolean2().optional(),
29447
29549
  skillOverrides: union([
29448
29550
  literal("off"),
29449
29551
  literal("user-invocable-only"),
@@ -30062,7 +30164,7 @@ var init_filesystem = __esm(() => {
30062
30164
 
30063
30165
  // src/permissions/permissionRuleParser.ts
30064
30166
  function setLegacyToolNameAliases(map) {
30065
- legacyToolNameAliases = map;
30167
+ legacyToolNameAliases = Object.assign(Object.create(null), map);
30066
30168
  }
30067
30169
  function normalizeLegacyToolName(name) {
30068
30170
  return legacyToolNameAliases[name] ?? name;
@@ -30137,7 +30239,7 @@ function findLastUnescapedChar(str, char) {
30137
30239
  }
30138
30240
  var legacyToolNameAliases;
30139
30241
  var init_permissionRuleParser = __esm(() => {
30140
- legacyToolNameAliases = {};
30242
+ legacyToolNameAliases = Object.create(null);
30141
30243
  });
30142
30244
 
30143
30245
  // src/permissions/mcpRuleNames.ts
@@ -30146,6 +30248,9 @@ function normalizeNameForMCP(name) {
30146
30248
  const normalized = folded.replace(/_+/g, "_").replace(/^_|_$/g, "");
30147
30249
  return normalized === "" ? folded : normalized;
30148
30250
  }
30251
+ function foldMcpNameForCompare(name) {
30252
+ return name.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_");
30253
+ }
30149
30254
  function mcpInfoFromString(toolString) {
30150
30255
  const parts = toolString.split("__");
30151
30256
  const [mcpPart, serverName, ...toolNameParts] = parts;
@@ -30215,9 +30320,17 @@ function toolMatchesRule(tool, rule) {
30215
30320
  if (rule.ruleValue.toolName === nameForRuleMatch) {
30216
30321
  return true;
30217
30322
  }
30218
- const ruleInfo = mcpInfoFromString(rule.ruleValue.toolName);
30219
- const toolInfo = mcpInfoFromString(nameForRuleMatch);
30220
- return ruleInfo !== null && toolInfo !== null && (ruleInfo.toolName === undefined || ruleInfo.toolName === "*") && ruleInfo.serverName === toolInfo.serverName;
30323
+ const toolInfo = tool.mcpInfo ?? mcpInfoFromString(nameForRuleMatch);
30324
+ const ruleName = rule.ruleValue.toolName;
30325
+ if (!toolInfo || !ruleName.startsWith("mcp__")) {
30326
+ return false;
30327
+ }
30328
+ if (foldMcpNameForCompare(ruleName) === foldMcpNameForCompare(nameForRuleMatch)) {
30329
+ return true;
30330
+ }
30331
+ const rest = ruleName.slice("mcp__".length);
30332
+ const ruleServerRaw = rest.endsWith("__*") ? rest.slice(0, -3) : rest;
30333
+ return foldMcpNameForCompare(ruleServerRaw) === foldMcpNameForCompare(toolInfo.serverName);
30221
30334
  }
30222
30335
  function toolAlwaysAllowedRule(context, tool) {
30223
30336
  return getAllowRules(context).find((rule) => toolMatchesRule(tool, rule)) || null;
@@ -36769,6 +36882,15 @@ function filterToolsForAgent({
36769
36882
  function computeChildSpawnDepth(parentOptions) {
36770
36883
  return (parentOptions?.spawnDepth ?? 0) + 1;
36771
36884
  }
36885
+ function resolveMcpServerDomainTools(toolName, available) {
36886
+ if (typeof toolName !== "string")
36887
+ return null;
36888
+ const info = mcpInfoFromString(toolName);
36889
+ if (!info || info.toolName !== undefined)
36890
+ return null;
36891
+ const prefix = getMcpPrefix(info.serverName);
36892
+ return available.filter((t) => t.name.startsWith(prefix));
36893
+ }
36772
36894
  function resolveAgentTools(agentDefinition, availableTools, allowFanOut = false) {
36773
36895
  const { tools: agentTools, disallowedTools, source } = agentDefinition;
36774
36896
  const filtered = filterToolsForAgent({
@@ -36799,7 +36921,18 @@ function resolveAgentTools(agentDefinition, availableTools, allowFanOut = false)
36799
36921
  seen.add(tool);
36800
36922
  }
36801
36923
  } else {
36802
- invalidTools.push(spec);
36924
+ const domain = resolveMcpServerDomainTools(toolName, allowed);
36925
+ if (domain && domain.length > 0) {
36926
+ validTools.push(spec);
36927
+ for (const t of domain) {
36928
+ if (!seen.has(t)) {
36929
+ resolved.push(t);
36930
+ seen.add(t);
36931
+ }
36932
+ }
36933
+ } else {
36934
+ invalidTools.push(spec);
36935
+ }
36803
36936
  }
36804
36937
  }
36805
36938
  return { hasWildcard: false, validTools, invalidTools, resolvedTools: resolved };
@@ -78318,7 +78451,7 @@ function getMcpDiscoveryInput() {
78318
78451
  return discoveryInput;
78319
78452
  }
78320
78453
  async function buildMcpServerConfigs(input) {
78321
- const servers = {};
78454
+ const servers = Object.create(null);
78322
78455
  for (const [name, raw] of Object.entries(input.settingsServers ?? {})) {
78323
78456
  const parsed = parseMcpServerConfig(raw);
78324
78457
  if (parsed) {
@@ -78549,6 +78682,7 @@ async function terminateChild(name, child) {
78549
78682
  function createMcpConnectionManager() {
78550
78683
  const connections = new Map;
78551
78684
  const pending = new Set;
78685
+ const pendingConnects = new Map;
78552
78686
  const connectFailures = new Map;
78553
78687
  function fail(name, config, error, authFailure = false) {
78554
78688
  const conn = {
@@ -78561,6 +78695,17 @@ function createMcpConnectionManager() {
78561
78695
  connections.set(name, conn);
78562
78696
  return conn;
78563
78697
  }
78698
+ function markBlocked(name, config, reason) {
78699
+ const conn = {
78700
+ name,
78701
+ type: "failed",
78702
+ config,
78703
+ error: `MCP server "${name}" blocked by enterprise policy: ${reason}`,
78704
+ blockedByPolicy: true
78705
+ };
78706
+ connections.set(name, conn);
78707
+ return conn;
78708
+ }
78564
78709
  async function connectStdio(name, config, opts) {
78565
78710
  const finalCommand = process.env.ATLAS_SHELL_PREFIX || config.command;
78566
78711
  const finalArgs = process.env.ATLAS_SHELL_PREFIX ? [[config.command, ...config.args ?? []].join(" ")] : config.args ?? [];
@@ -78618,7 +78763,7 @@ function createMcpConnectionManager() {
78618
78763
  };
78619
78764
  client.onClose(closeOnDrop);
78620
78765
  const initPromise = client.request("initialize", {
78621
- protocolVersion: "2025-03-26",
78766
+ protocolVersion: "2026-07-28",
78622
78767
  capabilities: {
78623
78768
  elicitation: {},
78624
78769
  roots: {}
@@ -78645,6 +78790,7 @@ function createMcpConnectionManager() {
78645
78790
  version: init.serverInfo.version
78646
78791
  }
78647
78792
  } : {},
78793
+ ...init.protocolVersion ? { negotiatedProtocolVersion: init.protocolVersion } : {},
78648
78794
  ...init.instructions ? { instructions: init.instructions } : {},
78649
78795
  config,
78650
78796
  cleanup: async () => {
@@ -78671,6 +78817,21 @@ function createMcpConnectionManager() {
78671
78817
  }
78672
78818
  }
78673
78819
  async function connect(name, config, opts) {
78820
+ const existing = connections.get(name);
78821
+ if (existing?.type === "connected")
78822
+ return existing;
78823
+ const inflight = pendingConnects.get(name);
78824
+ if (inflight)
78825
+ return inflight;
78826
+ const attempt = connectOnce(name, config, opts);
78827
+ pendingConnects.set(name, attempt);
78828
+ try {
78829
+ return await attempt;
78830
+ } finally {
78831
+ pendingConnects.delete(name);
78832
+ }
78833
+ }
78834
+ async function connectOnce(name, config, opts) {
78674
78835
  const existing = connections.get(name);
78675
78836
  if (existing?.type === "connected")
78676
78837
  return existing;
@@ -78712,7 +78873,8 @@ function createMcpConnectionManager() {
78712
78873
  await manager.close(name);
78713
78874
  }
78714
78875
  },
78715
- getPendingServerNames: () => [...pending]
78876
+ getPendingServerNames: () => [...pending],
78877
+ markBlocked
78716
78878
  };
78717
78879
  return manager;
78718
78880
  }
@@ -78727,6 +78889,143 @@ var init_mcpConnectionManager = __esm(() => {
78727
78889
  init_mcpFetch();
78728
78890
  });
78729
78891
 
78892
+ // src/mcp/mcpPolicy.ts
78893
+ function getMcpPolicyFromSettings(settings) {
78894
+ if (typeof settings !== "object" || settings === null)
78895
+ return {};
78896
+ const rec = settings;
78897
+ return {
78898
+ ...rec.allowedMcpServers !== undefined ? { allowedMcpServers: rec.allowedMcpServers } : {},
78899
+ ...rec.deniedMcpServers !== undefined ? { deniedMcpServers: rec.deniedMcpServers } : {}
78900
+ };
78901
+ }
78902
+ function getMcpPolicyInput() {
78903
+ return policyInput;
78904
+ }
78905
+ function normalizePolicyEntries(raw) {
78906
+ if (!Array.isArray(raw))
78907
+ return [];
78908
+ const out = [];
78909
+ for (const entry of raw) {
78910
+ if (typeof entry === "string") {
78911
+ out.push({ kind: "name", value: entry });
78912
+ continue;
78913
+ }
78914
+ if (typeof entry !== "object" || entry === null)
78915
+ continue;
78916
+ const rec = entry;
78917
+ if (typeof rec.serverName === "string") {
78918
+ out.push({ kind: "name", value: rec.serverName });
78919
+ } else if (Array.isArray(rec.serverCommand) && rec.serverCommand.every((c) => typeof c === "string")) {
78920
+ out.push({ kind: "command", value: rec.serverCommand });
78921
+ } else if (typeof rec.serverUrl === "string") {
78922
+ out.push({ kind: "url", value: rec.serverUrl });
78923
+ }
78924
+ }
78925
+ return out;
78926
+ }
78927
+ function getServerCommandArray(config) {
78928
+ const t = config.type;
78929
+ if (t !== undefined && t !== "stdio") {
78930
+ return null;
78931
+ }
78932
+ const stdioConfig = config;
78933
+ return [stdioConfig.command, ...stdioConfig.args ?? []];
78934
+ }
78935
+ function commandArraysMatch(a, b) {
78936
+ if (a.length !== b.length) {
78937
+ return false;
78938
+ }
78939
+ return a.every((val, idx) => val === b[idx]);
78940
+ }
78941
+ function getServerUrl(config) {
78942
+ return "url" in config ? config.url : null;
78943
+ }
78944
+ function urlPatternToRegex(pattern) {
78945
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
78946
+ const regexStr = escaped.replace(/\*/g, ".*");
78947
+ return new RegExp(`^${regexStr}$`);
78948
+ }
78949
+ function urlMatchesPattern(url, pattern) {
78950
+ return urlPatternToRegex(pattern).test(url);
78951
+ }
78952
+ function isDeniedByEntries(serverName, config, entries) {
78953
+ for (const entry of entries) {
78954
+ if (entry.kind === "name" && entry.value === serverName)
78955
+ return true;
78956
+ }
78957
+ const serverCommand = getServerCommandArray(config);
78958
+ if (serverCommand) {
78959
+ for (const entry of entries) {
78960
+ if (entry.kind === "command" && commandArraysMatch(entry.value, serverCommand)) {
78961
+ return true;
78962
+ }
78963
+ }
78964
+ }
78965
+ const serverUrl = getServerUrl(config);
78966
+ if (serverUrl) {
78967
+ for (const entry of entries) {
78968
+ if (entry.kind === "url" && urlMatchesPattern(serverUrl, entry.value)) {
78969
+ return true;
78970
+ }
78971
+ }
78972
+ }
78973
+ return false;
78974
+ }
78975
+ function isAllowedByEntries(serverName, config, entries) {
78976
+ const hasCommandEntries = entries.some((e) => e.kind === "command");
78977
+ const hasUrlEntries = entries.some((e) => e.kind === "url");
78978
+ const serverCommand = getServerCommandArray(config);
78979
+ const serverUrl = getServerUrl(config);
78980
+ if (serverCommand) {
78981
+ if (hasCommandEntries) {
78982
+ return entries.some((e) => e.kind === "command" && commandArraysMatch(e.value, serverCommand));
78983
+ }
78984
+ return entries.some((e) => e.kind === "name" && e.value === serverName);
78985
+ }
78986
+ if (serverUrl) {
78987
+ if (hasUrlEntries) {
78988
+ return entries.some((e) => e.kind === "url" && urlMatchesPattern(serverUrl, e.value));
78989
+ }
78990
+ return entries.some((e) => e.kind === "name" && e.value === serverName);
78991
+ }
78992
+ return entries.some((e) => e.kind === "name" && e.value === serverName);
78993
+ }
78994
+ function checkMcpServerPolicy(serverName, config, policy) {
78995
+ const p = policy ?? getMcpPolicyInput() ?? {};
78996
+ const denied = normalizePolicyEntries(p.deniedMcpServers);
78997
+ if (isDeniedByEntries(serverName, config, denied)) {
78998
+ return { blocked: true, reason: "denied by policy (deniedMcpServers)" };
78999
+ }
79000
+ if (!Array.isArray(p.allowedMcpServers))
79001
+ return { blocked: false };
79002
+ if (p.allowedMcpServers.length === 0) {
79003
+ return {
79004
+ blocked: true,
79005
+ reason: "not in allowedMcpServers allowlist (empty allowlist blocks all servers)"
79006
+ };
79007
+ }
79008
+ const allowed = normalizePolicyEntries(p.allowedMcpServers);
79009
+ if (isAllowedByEntries(serverName, config, allowed)) {
79010
+ return { blocked: false };
79011
+ }
79012
+ return { blocked: true, reason: "not in allowedMcpServers allowlist" };
79013
+ }
79014
+ function filterMcpServersByPolicy(configs, policy) {
79015
+ const allowed = {};
79016
+ const blocked = [];
79017
+ for (const [name, config] of Object.entries(configs)) {
79018
+ const verdict = checkMcpServerPolicy(name, config, policy);
79019
+ if (verdict.blocked) {
79020
+ blocked.push({ name, reason: verdict.reason ?? "blocked by policy" });
79021
+ } else {
79022
+ allowed[name] = config;
79023
+ }
79024
+ }
79025
+ return { allowed, blocked };
79026
+ }
79027
+ var policyInput = null;
79028
+
78730
79029
  // src/mcp/index.ts
78731
79030
  var init_mcp3 = __esm(() => {
78732
79031
  init_types6();
@@ -79827,12 +80126,12 @@ var LEGACY_TOOL_NAME_ALIASES;
79827
80126
  var init_legacyToolNameAliases = __esm(() => {
79828
80127
  init_permissions3();
79829
80128
  init_toolNames();
79830
- LEGACY_TOOL_NAME_ALIASES = {
80129
+ LEGACY_TOOL_NAME_ALIASES = Object.assign(Object.create(null), {
79831
80130
  Task: AGENT_TOOL_NAME,
79832
80131
  KillShell: TASK_STOP_TOOL_NAME,
79833
80132
  AgentOutputTool: TASK_OUTPUT_TOOL_NAME,
79834
80133
  BashOutputTool: TASK_OUTPUT_TOOL_NAME
79835
- };
80134
+ });
79836
80135
  setLegacyToolNameAliases(LEGACY_TOOL_NAME_ALIASES);
79837
80136
  });
79838
80137
 
@@ -81784,9 +82083,14 @@ function resolveAutoCompactWindowSingle(setting) {
81784
82083
  }
81785
82084
  return {};
81786
82085
  }
82086
+ function lookupAutoCompactWindowSetting(perModel, model) {
82087
+ if (!model)
82088
+ return perModel.default;
82089
+ return perModel[model] ?? perModel[stripProviderPrefix(model)] ?? perModel.default;
82090
+ }
81787
82091
  function resolveAutoCompactWindow(setting, model) {
81788
82092
  const perModel = normalizeAutoCompactWindowSetting(setting);
81789
- const chosen = model && perModel[model] || perModel.default;
82093
+ const chosen = lookupAutoCompactWindowSetting(perModel, model);
81790
82094
  return resolveAutoCompactWindowSingle(chosen);
81791
82095
  }
81792
82096
  function parseAutoCompactTierInput(raw) {
@@ -81822,6 +82126,7 @@ function parseAutoCompactTierArg(raw) {
81822
82126
  }
81823
82127
  var AUTOCOMPACT_PRESET_WINDOW_TIERS;
81824
82128
  var init_autoCompactWindow = __esm(() => {
82129
+ init_modelprovider2();
81825
82130
  AUTOCOMPACT_PRESET_WINDOW_TIERS = [
81826
82131
  1e5,
81827
82132
  128000,
@@ -81830,6 +82135,56 @@ var init_autoCompactWindow = __esm(() => {
81830
82135
  ];
81831
82136
  });
81832
82137
 
82138
+ // src/engine/context/idleCompaction.ts
82139
+ function resolveIdleCompactionConfig(settingsRaw, envRaw) {
82140
+ const enabled = settingsRaw !== false;
82141
+ let minTokens = IDLE_COMPACT_MIN_TOKENS;
82142
+ if (envRaw !== undefined) {
82143
+ const parsed = Number(envRaw);
82144
+ if (Number.isInteger(parsed) && parsed >= 1)
82145
+ minTokens = parsed;
82146
+ }
82147
+ return { enabled, minTokens };
82148
+ }
82149
+ function shouldIdleCompact(config, idleMs, totalTokens) {
82150
+ return config.enabled && Number.isFinite(idleMs) && idleMs >= IDLE_COMPACT_TRIGGER_MS && Number.isFinite(totalTokens) && totalTokens >= config.minTokens;
82151
+ }
82152
+ function getIdleMs(messages, now = Date.now()) {
82153
+ let lastAssistant;
82154
+ for (let i = messages.length - 1;i >= 0; i--) {
82155
+ const m = messages[i];
82156
+ if (m && m.type === "assistant") {
82157
+ lastAssistant = m;
82158
+ break;
82159
+ }
82160
+ }
82161
+ if (!lastAssistant)
82162
+ return Number.NaN;
82163
+ const raw = lastAssistant.timestamp;
82164
+ if (raw === undefined || raw === null)
82165
+ return Number.NaN;
82166
+ const ts = typeof raw === "number" ? raw : new Date(String(raw)).getTime();
82167
+ if (!Number.isFinite(ts) || ts <= 0)
82168
+ return Number.NaN;
82169
+ return now - ts;
82170
+ }
82171
+ function setIdleCompactionSettingsSource(next) {
82172
+ idleCompactionSettingsSource = next;
82173
+ }
82174
+ function getIdleCompactionConfig() {
82175
+ return resolveIdleCompactionConfig(idleCompactionSettingsSource?.(), process.env.ATLAS_IDLE_COMPACT_MIN_TOKENS);
82176
+ }
82177
+ function resetIdleCompactionForTesting() {
82178
+ idleCompactionSettingsSource = null;
82179
+ }
82180
+ var PROMPT_CACHE_TTL_MS = 3600000, IDLE_COMPACT_TRIGGER_MS = 3240000, IDLE_COMPACT_MIN_TOKENS = 200000, IDLE_COMPACTION_CONFIG_DEFAULTS, idleCompactionSettingsSource = null;
82181
+ var init_idleCompaction = __esm(() => {
82182
+ IDLE_COMPACTION_CONFIG_DEFAULTS = {
82183
+ enabled: true,
82184
+ minTokens: IDLE_COMPACT_MIN_TOKENS
82185
+ };
82186
+ });
82187
+
81833
82188
  // src/engine/context/autoCompact.ts
81834
82189
  import { randomUUID as randomUUID17 } from "crypto";
81835
82190
  function resolveModelContextWindow(model) {
@@ -81975,7 +82330,19 @@ async function shouldAutoCompact(messages, deps) {
81975
82330
  if (!Number.isFinite(tokenCount)) {
81976
82331
  return false;
81977
82332
  }
81978
- return tokenCount >= getAutoCompactThreshold(deps.contextWindow, deps.maxOutputTokens, deps.pctOverride, deps.windowOverride);
82333
+ const thinkingBudget = deps.thinkingBudgetTokens !== undefined && Number.isFinite(deps.thinkingBudgetTokens) ? deps.thinkingBudgetTokens : 0;
82334
+ const thresholdMet = tokenCount + thinkingBudget >= getAutoCompactThreshold(deps.contextWindow, deps.maxOutputTokens, deps.pctOverride, deps.windowOverride);
82335
+ if (thresholdMet) {
82336
+ return true;
82337
+ }
82338
+ const idleConfig = getIdleCompactionConfig();
82339
+ if (idleConfig.enabled) {
82340
+ const idleMs = getIdleMs(messages);
82341
+ if (shouldIdleCompact(idleConfig, idleMs, tokenCount)) {
82342
+ return true;
82343
+ }
82344
+ }
82345
+ return false;
81979
82346
  }
81980
82347
  async function autoCompactIfNeeded(messages, tracking, deps) {
81981
82348
  if (tracking?.consecutiveFailures !== undefined && tracking.consecutiveFailures >= MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES) {
@@ -82012,6 +82379,7 @@ var init_autoCompact = __esm(() => {
82012
82379
  init_config();
82013
82380
  init_compact();
82014
82381
  init_autoCompactWindow();
82382
+ init_idleCompaction();
82015
82383
  });
82016
82384
 
82017
82385
  // src/engine/context/autoCompactRich.ts
@@ -82503,6 +82871,7 @@ var init_autoCompactCircuit = __esm(() => {
82503
82871
  // src/engine/context/index.ts
82504
82872
  var init_context = __esm(() => {
82505
82873
  init_autoCompact();
82874
+ init_idleCompaction();
82506
82875
  init_autoCompactWindow();
82507
82876
  init_autoCompact();
82508
82877
  init_autoCompactRich();
@@ -82648,6 +83017,8 @@ async function queryAgentLoop(deps, args) {
82648
83017
  let turns = 0;
82649
83018
  let terminated = false;
82650
83019
  let lastRound;
83020
+ let activeTools = tools;
83021
+ const degradedTools = new Set;
82651
83022
  const maxGoalTurns = args.context?.maxGoalTurns ?? DEFAULT_MAX_GOAL_TURNS;
82652
83023
  let goalTurns = 0;
82653
83024
  let deferredToolUse;
@@ -82660,7 +83031,7 @@ async function queryAgentLoop(deps, args) {
82660
83031
  deps.emit?.({ type: "loop_start", messageCount: messages.length });
82661
83032
  while (turns < maxTurns) {
82662
83033
  turns++;
82663
- if (args.context?.autoCompact) {
83034
+ if (args.context?.autoCompact && !deps.signal?.aborted) {
82664
83035
  const oc = await autoCompactIfNeeded(messages, tracking, args.context.autoCompact);
82665
83036
  if (oc.wasCompacted && oc.compactionResult && !oc.compactionResult.compactionSkipped) {
82666
83037
  messages = buildPostCompactMessages(oc.compactionResult);
@@ -82682,7 +83053,7 @@ async function queryAgentLoop(deps, args) {
82682
83053
  }
82683
83054
  }
82684
83055
  deps.transcript?.reAppendSessionMetadata?.();
82685
- } else if (oc.consecutiveFailures !== undefined) {
83056
+ } else if (oc.consecutiveFailures !== undefined && !deps.signal?.aborted) {
82686
83057
  tracking = { ...tracking, consecutiveFailures: oc.consecutiveFailures };
82687
83058
  reportAutoCompactCircuitFailures(oc.consecutiveFailures);
82688
83059
  }
@@ -82690,6 +83061,24 @@ async function queryAgentLoop(deps, args) {
82690
83061
  deps.emit?.({ type: "compacted", turn: turns, messages });
82691
83062
  }
82692
83063
  }
83064
+ if (deps.refreshRoundContext) {
83065
+ try {
83066
+ const refresh = deps.refreshRoundContext(messages);
83067
+ if (refresh) {
83068
+ if (refresh.tools) {
83069
+ activeTools = degradedTools.size > 0 ? refresh.tools.filter((t) => !degradedTools.has(t.name)) : refresh.tools;
83070
+ }
83071
+ if (refresh.appendedMessages && refresh.appendedMessages.length > 0) {
83072
+ messages = [...messages, ...refresh.appendedMessages];
83073
+ if (deps.transcript) {
83074
+ await deps.transcript.record(messages);
83075
+ }
83076
+ }
83077
+ }
83078
+ } catch (refreshErr) {
83079
+ logForDebugging(`[round-context-refresh] failed: ${errorMessage(refreshErr)}`);
83080
+ }
83081
+ }
82693
83082
  deps.emit?.({ type: "round_start", turn: turns });
82694
83083
  let reactiveRetried = false;
82695
83084
  let effectiveDeps = deps;
@@ -82697,7 +83086,7 @@ async function queryAgentLoop(deps, args) {
82697
83086
  for (;; ) {
82698
83087
  const roundInputLen = messages.length;
82699
83088
  try {
82700
- lastRound = await queryOneRound(effectiveDeps, tools, messages);
83089
+ lastRound = await queryOneRound(effectiveDeps, activeTools, messages);
82701
83090
  } catch (err) {
82702
83091
  if (!reactiveRetried && deps.reactiveCompact !== undefined && isReactiveCompactEnabled() && isReactiveCompactRecoverableError(err)) {
82703
83092
  reactiveRetried = true;
@@ -82720,6 +83109,13 @@ async function queryAgentLoop(deps, args) {
82720
83109
  continue;
82721
83110
  }
82722
83111
  }
83112
+ const rejectedTool = parseToolSchemaRejectionError(err);
83113
+ if (rejectedTool && !degradedTools.has(rejectedTool) && activeTools.some((t) => t.name === rejectedTool)) {
83114
+ degradedTools.add(rejectedTool);
83115
+ activeTools = activeTools.filter((t) => t.name !== rejectedTool);
83116
+ logForDebugging(`[tool-schema-strip] 网关拒绝工具 '${rejectedTool}' 的 input schema,本会话剥除其参数后续跑(tools ${activeTools.length} 个)`);
83117
+ continue;
83118
+ }
82723
83119
  const nextRef = nextFallbackRef(deps.fallbackModels, triedFallbackRefs);
82724
83120
  if (nextRef && shouldRetryModelError(err, deps.signal)) {
82725
83121
  triedFallbackRefs.add(nextRef);
@@ -86808,7 +87204,12 @@ async function connectMcpStartup(args) {
86808
87204
  }) : {};
86809
87205
  const dynamicNames = new Set(Object.keys(dynamicConfigs));
86810
87206
  const allConfigs = strictMcpConfig ? dynamicConfigs : { ...baseConfigs, ...dynamicConfigs };
86811
- const connectAll = () => Promise.allSettled(Object.entries(allConfigs).map(([name, config]) => manager.connect(name, config, dynamicNames.has(name) ? { connectionTimeoutMs: 5000 } : undefined)));
87207
+ const policy = getMcpPolicyInput() ?? getMcpPolicyFromSettings(getSettingsWithErrors().settings);
87208
+ const { allowed, blocked } = filterMcpServersByPolicy(allConfigs, policy);
87209
+ for (const b of blocked) {
87210
+ manager.markBlocked(b.name, allConfigs[b.name], b.reason);
87211
+ }
87212
+ const connectAll = () => Promise.allSettled(Object.entries(allowed).map(([name, config]) => manager.connect(name, config, dynamicNames.has(name) ? { connectionTimeoutMs: 5000 } : undefined)));
86812
87213
  const nonBlocking = isMcpConnectionNonBlocking();
86813
87214
  if (nonBlocking) {
86814
87215
  connectAll();
@@ -88067,6 +88468,10 @@ async function mapConcurrent(items, fn, concurrency) {
88067
88468
  return results;
88068
88469
  }
88069
88470
  async function checkMcpServerHealth(manager, name, server) {
88471
+ const policy = getMcpPolicyInput() ?? getMcpPolicyFromSettings(getSettingsWithErrors().settings);
88472
+ if (checkMcpServerPolicy(name, server, policy).blocked) {
88473
+ return "✗ Blocked by enterprise policy";
88474
+ }
88070
88475
  try {
88071
88476
  const result = await manager.connect(name, server);
88072
88477
  if (result.type === "connected") {
@@ -88362,6 +88767,7 @@ Warning: The command "${actualCommand}" looks like a URL, but is being interpret
88362
88767
  }
88363
88768
  var init_mcp4 = __esm(() => {
88364
88769
  init_mcp3();
88770
+ init_engine();
88365
88771
  init_entryInit();
88366
88772
  init_mcpConfigWrite();
88367
88773
  init_setup();
@@ -124303,8 +124709,8 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
124303
124709
  mcpServers: record(string2(), any()).optional(),
124304
124710
  allowedMcpServers: any().optional(),
124305
124711
  deniedMcpServers: any().optional(),
124306
- enabledMcpjsonServers: array(string2()).optional(),
124307
- disabledMcpjsonServers: array(string2()).optional(),
124712
+ enabledMcpjsonServers: union([string2(), array(string2())]).transform((v) => Array.isArray(v) ? v : [v]).optional(),
124713
+ disabledMcpjsonServers: union([string2(), array(string2())]).transform((v) => Array.isArray(v) ? v : [v]).optional(),
124308
124714
  enabledPlugins: record(string2(), any()).optional(),
124309
124715
  pluginConfigs: any().optional(),
124310
124716
  extraKnownMarketplaces: any().optional(),
@@ -124333,6 +124739,7 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
124333
124739
  prefersReducedMotion: boolean2().optional(),
124334
124740
  syntaxHighlightingDisabled: boolean2().optional(),
124335
124741
  spinnerTipsEnabled: boolean2().optional(),
124742
+ idleCompaction: boolean2().optional(),
124336
124743
  spinnerTipsOverride: any().optional(),
124337
124744
  spinnerVerbs: any().optional(),
124338
124745
  statusLine: any().optional(),
@@ -124644,12 +125051,12 @@ function findLastUnescapedChar2(str, char) {
124644
125051
  var LEGACY_TOOL_NAME_ALIASES2;
124645
125052
  var init_permissionRuleParser2 = __esm(() => {
124646
125053
  init_constants6();
124647
- LEGACY_TOOL_NAME_ALIASES2 = {
125054
+ LEGACY_TOOL_NAME_ALIASES2 = Object.assign(Object.create(null), {
124648
125055
  Task: AGENT_TOOL_NAME2,
124649
125056
  KillShell: TASK_STOP_TOOL_NAME2,
124650
125057
  AgentOutputTool: TASK_OUTPUT_TOOL_NAME2,
124651
125058
  BashOutputTool: TASK_OUTPUT_TOOL_NAME2
124652
- };
125059
+ });
124653
125060
  });
124654
125061
 
124655
125062
  // src/tui/utils/settings/toolValidationConfig.ts
@@ -132971,6 +133378,13 @@ function getPersistedEffortForModel(model) {
132971
133378
  if (key.toLowerCase() === wanted)
132972
133379
  return level;
132973
133380
  }
133381
+ const base = stripProviderPrefix(model).toLowerCase();
133382
+ if (base !== wanted) {
133383
+ for (const [key, level] of Object.entries(getEffortByModel())) {
133384
+ if (key.toLowerCase() === base)
133385
+ return level;
133386
+ }
133387
+ }
132974
133388
  return;
132975
133389
  }
132976
133390
  function withEffortForModel(model, level) {
@@ -133050,6 +133464,7 @@ var init_effort2 = __esm(() => {
133050
133464
  init_thinking();
133051
133465
  init_settings3();
133052
133466
  init_envUtils2();
133467
+ init_modelprovider2();
133053
133468
  EFFORT_LEVELS2 = [
133054
133469
  "low",
133055
133470
  "medium",
@@ -151291,28 +151706,28 @@ function getEventPriority(eventType) {
151291
151706
  case "focus":
151292
151707
  case "blur":
151293
151708
  case "paste":
151294
- return import_constants54.DiscreteEventPriority;
151709
+ return import_constants56.DiscreteEventPriority;
151295
151710
  case "resize":
151296
151711
  case "scroll":
151297
151712
  case "mousemove":
151298
- return import_constants54.ContinuousEventPriority;
151713
+ return import_constants56.ContinuousEventPriority;
151299
151714
  default:
151300
- return import_constants54.DefaultEventPriority;
151715
+ return import_constants56.DefaultEventPriority;
151301
151716
  }
151302
151717
  }
151303
151718
 
151304
151719
  class Dispatcher {
151305
151720
  currentEvent = null;
151306
- currentUpdatePriority = import_constants54.DefaultEventPriority;
151721
+ currentUpdatePriority = import_constants56.DefaultEventPriority;
151307
151722
  discreteUpdates = null;
151308
151723
  resolveEventPriority() {
151309
- if (this.currentUpdatePriority !== import_constants54.NoEventPriority) {
151724
+ if (this.currentUpdatePriority !== import_constants56.NoEventPriority) {
151310
151725
  return this.currentUpdatePriority;
151311
151726
  }
151312
151727
  if (this.currentEvent) {
151313
151728
  return getEventPriority(this.currentEvent.type);
151314
151729
  }
151315
- return import_constants54.DefaultEventPriority;
151730
+ return import_constants56.DefaultEventPriority;
151316
151731
  }
151317
151732
  dispatch(target, event) {
151318
151733
  const previousEvent = this.currentEvent;
@@ -151337,18 +151752,18 @@ class Dispatcher {
151337
151752
  dispatchContinuous(target, event) {
151338
151753
  const previousPriority = this.currentUpdatePriority;
151339
151754
  try {
151340
- this.currentUpdatePriority = import_constants54.ContinuousEventPriority;
151755
+ this.currentUpdatePriority = import_constants56.ContinuousEventPriority;
151341
151756
  return this.dispatch(target, event);
151342
151757
  } finally {
151343
151758
  this.currentUpdatePriority = previousPriority;
151344
151759
  }
151345
151760
  }
151346
151761
  }
151347
- var import_constants54;
151762
+ var import_constants56;
151348
151763
  var init_dispatcher = __esm(() => {
151349
151764
  init_log5();
151350
151765
  init_event_handlers();
151351
- import_constants54 = __toESM(require_constants2(), 1);
151766
+ import_constants56 = __toESM(require_constants2(), 1);
151352
151767
  });
151353
151768
 
151354
151769
  // src/tui/ink/events/terminal-event.ts
@@ -160155,7 +160570,7 @@ function applyPositionedHighlight(screen, stylePool, positions, rowOffset, curre
160155
160570
  }
160156
160571
  return true;
160157
160572
  }
160158
- var import_constants56, timing;
160573
+ var import_constants58, timing;
160159
160574
  var init_render_to_screen = __esm(() => {
160160
160575
  init_debug();
160161
160576
  init_dom();
@@ -160164,7 +160579,7 @@ var init_render_to_screen = __esm(() => {
160164
160579
  init_reconciler();
160165
160580
  init_render_node_to_output();
160166
160581
  init_screen();
160167
- import_constants56 = __toESM(require_constants2(), 1);
160582
+ import_constants58 = __toESM(require_constants2(), 1);
160168
160583
  timing = { reconcile: 0, yoga: 0, paint: 0, scan: 0, calls: 0 };
160169
160584
  });
160170
160585
 
@@ -160470,7 +160885,7 @@ class Ink {
160470
160885
  };
160471
160886
  }
160472
160887
  };
160473
- this.container = reconciler_default.createContainer(this.rootNode, import_constants57.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
160888
+ this.container = reconciler_default.createContainer(this.rootNode, import_constants59.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
160474
160889
  if (false) {}
160475
160890
  }
160476
160891
  handleResume = () => {
@@ -161283,7 +161698,7 @@ function drainStdin(stdin = process.stdin) {
161283
161698
  }
161284
161699
  }
161285
161700
  }
161286
- var import_constants57, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
161701
+ var import_constants59, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
161287
161702
  var init_ink = __esm(() => {
161288
161703
  init_noop();
161289
161704
  init_throttle2();
@@ -161316,7 +161731,7 @@ var init_ink = __esm(() => {
161316
161731
  init_dec();
161317
161732
  init_osc();
161318
161733
  init_useTerminalNotification();
161319
- import_constants57 = __toESM(require_constants2(), 1);
161734
+ import_constants59 = __toESM(require_constants2(), 1);
161320
161735
  jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
161321
161736
  ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
161322
161737
  x: 0,
@@ -171913,6 +172328,7 @@ function parseAgentFromJson(name, definition, source = "flagSettings") {
171913
172328
  ...parsed.mcpServers && parsed.mcpServers.length > 0 ? { mcpServers: parsed.mcpServers } : {},
171914
172329
  ...parsed.hooks ? { hooks: parsed.hooks } : {},
171915
172330
  ...parsed.maxTurns !== undefined ? { maxTurns: parsed.maxTurns } : {},
172331
+ ...parsed.autoCompactWindow !== undefined ? { autoCompactWindow: parsed.autoCompactWindow } : {},
171916
172332
  ...parsed.skills && parsed.skills.length > 0 ? { skills: parsed.skills } : {},
171917
172333
  ...parsed.initialPrompt ? { initialPrompt: parsed.initialPrompt } : {},
171918
172334
  ...parsed.background ? { background: parsed.background } : {},
@@ -171999,6 +172415,11 @@ function parseAgentFromMarkdown2(filePath, baseDir, frontmatter, content, source
171999
172415
  if (maxTurnsRaw !== undefined && maxTurns === undefined) {
172000
172416
  logForDebugging3(`Agent file ${filePath} has invalid maxTurns '${maxTurnsRaw}'. Must be a positive integer.`);
172001
172417
  }
172418
+ const autoCompactWindowRaw = frontmatter["autoCompactWindow"];
172419
+ const autoCompactWindow = parsePositiveIntFromFrontmatter(autoCompactWindowRaw);
172420
+ if (autoCompactWindowRaw !== undefined && autoCompactWindow === undefined) {
172421
+ logForDebugging3(`Agent file ${filePath} has invalid autoCompactWindow '${autoCompactWindowRaw}'. Must be a positive integer (tokens).`);
172422
+ }
172002
172423
  const filename = basename16(filePath, ".md");
172003
172424
  let tools = parseAgentToolsFromFrontmatter2(frontmatter["tools"]);
172004
172425
  if (isAutoMemoryEnabled2() && memory && tools !== undefined) {
@@ -172058,6 +172479,7 @@ function parseAgentFromMarkdown2(filePath, baseDir, frontmatter, content, source
172058
172479
  ...parsedEffort !== undefined ? { effort: parsedEffort } : {},
172059
172480
  ...isValidPermissionMode ? { permissionMode: permissionModeRaw } : {},
172060
172481
  ...maxTurns !== undefined ? { maxTurns } : {},
172482
+ ...autoCompactWindow !== undefined ? { autoCompactWindow } : {},
172061
172483
  ...background ? { background } : {},
172062
172484
  ...memory ? { memory } : {},
172063
172485
  ...isolation ? { isolation } : {}
@@ -172109,6 +172531,7 @@ var init_loadAgentsDir2 = __esm(() => {
172109
172531
  mcpServers: array(AgentMcpServerSpecSchema2()).optional(),
172110
172532
  hooks: HooksSchema2().optional(),
172111
172533
  maxTurns: number2().int().positive().optional(),
172534
+ autoCompactWindow: number2().int().positive().optional(),
172112
172535
  skills: array(string2()).optional(),
172113
172536
  initialPrompt: string2().optional(),
172114
172537
  memory: _enum(["user", "project", "local"]).optional(),
@@ -180708,6 +181131,9 @@ __export(exports_engineCompat, {
180708
181131
  HookCommandSchema: () => HookCommandSchema,
180709
181132
  HookMatcherSchema: () => HookMatcherSchema,
180710
181133
  HooksSchema: () => HooksSchema,
181134
+ IDLE_COMPACTION_CONFIG_DEFAULTS: () => IDLE_COMPACTION_CONFIG_DEFAULTS,
181135
+ IDLE_COMPACT_MIN_TOKENS: () => IDLE_COMPACT_MIN_TOKENS,
181136
+ IDLE_COMPACT_TRIGGER_MS: () => IDLE_COMPACT_TRIGGER_MS,
180711
181137
  INTERNAL_WORKER_TOOLS: () => INTERNAL_WORKER_TOOLS,
180712
181138
  INTERRUPT_MESSAGE: () => INTERRUPT_MESSAGE,
180713
181139
  INTERRUPT_MESSAGE_FOR_TOOL_USE: () => INTERRUPT_MESSAGE_FOR_TOOL_USE,
@@ -180731,6 +181157,7 @@ __export(exports_engineCompat, {
180731
181157
  NotebookEditTool: () => NotebookEditTool,
180732
181158
  PANEL_GRACE_MS: () => PANEL_GRACE_MS,
180733
181159
  POLL_INTERVAL_MS: () => POLL_INTERVAL_MS2,
181160
+ PROMPT_CACHE_TTL_MS: () => PROMPT_CACHE_TTL_MS,
180734
181161
  PTL_RETRY_MARKER: () => PTL_RETRY_MARKER,
180735
181162
  PermissionModeSchema: () => PermissionModeSchema,
180736
181163
  PlanApprovalRequestMessageSchema: () => PlanApprovalRequestMessageSchema,
@@ -180984,6 +181411,8 @@ __export(exports_engineCompat, {
180984
181411
  getGoalPausedReason: () => getGoalPausedReason,
180985
181412
  getGoalStateForPersistence: () => getGoalStateForPersistence,
180986
181413
  getHooksConfigFromSnapshot: () => getHooksConfigFromSnapshot,
181414
+ getIdleCompactionConfig: () => getIdleCompactionConfig,
181415
+ getIdleMs: () => getIdleMs,
180987
181416
  getInboxPath: () => getInboxPath,
180988
181417
  getInitialSettings: () => getInitialSettings,
180989
181418
  getLastPeerDmSummary: () => getLastPeerDmSummary,
@@ -181156,6 +181585,7 @@ __export(exports_engineCompat, {
181156
181585
  lock: () => lock,
181157
181586
  lockSync: () => lockSync,
181158
181587
  looksLikePrompt: () => looksLikePrompt,
181588
+ lookupAutoCompactWindowSetting: () => lookupAutoCompactWindowSetting,
181159
181589
  makeDeferredToolUseMarker: () => makeDeferredToolUseMarker,
181160
181590
  markAgentsNotified: () => markAgentsNotified,
181161
181591
  markCronTasksFired: () => markCronTasksFired,
@@ -181256,6 +181686,7 @@ __export(exports_engineCompat, {
181256
181686
  resetDomainMountForTests: () => resetDomainMountForTests,
181257
181687
  resetGoalStateForTesting: () => resetGoalStateForTesting,
181258
181688
  resetHooksConfigSnapshot: () => resetHooksConfigSnapshot,
181689
+ resetIdleCompactionForTesting: () => resetIdleCompactionForTesting,
181259
181690
  resetMcpClientRegistry: () => resetMcpClientRegistry,
181260
181691
  resetMcpSkillCommandSource: () => resetMcpSkillCommandSource,
181261
181692
  resetMicrocompactState: () => resetMicrocompactState,
@@ -181278,6 +181709,7 @@ __export(exports_engineCompat, {
181278
181709
  resolveAgentTools: () => resolveAgentTools,
181279
181710
  resolveAutoCompactWindow: () => resolveAutoCompactWindow,
181280
181711
  resolveGitDir: () => resolveGitDir,
181712
+ resolveIdleCompactionConfig: () => resolveIdleCompactionConfig,
181281
181713
  resolveRef: () => resolveRef,
181282
181714
  resolveWebSearchApiKey: () => resolveWebSearchApiKey,
181283
181715
  resolveWebSearchProvider: () => resolveWebSearchProvider,
@@ -181315,6 +181747,7 @@ __export(exports_engineCompat, {
181315
181747
  setCompactPorts: () => setCompactPorts,
181316
181748
  setCronJitterConfigProvider: () => setCronJitterConfigProvider,
181317
181749
  setDynamicTeamContext: () => setDynamicTeamContext,
181750
+ setIdleCompactionSettingsSource: () => setIdleCompactionSettingsSource,
181318
181751
  setLastSummarizedMessageId: () => setLastSummarizedMessageId,
181319
181752
  setLeaderTeamName: () => setLeaderTeamName,
181320
181753
  setMcpClientRegistry: () => setMcpClientRegistry,
@@ -181343,6 +181776,7 @@ __export(exports_engineCompat, {
181343
181776
  shouldAutoCompact: () => shouldAutoCompact,
181344
181777
  shouldDisableAllHooksIncludingManaged: () => shouldDisableAllHooksIncludingManaged,
181345
181778
  shouldDisableBypassPermissions: () => shouldDisableBypassPermissions,
181779
+ shouldIdleCompact: () => shouldIdleCompact,
181346
181780
  shouldNudgeForSnips: () => shouldNudgeForSnips,
181347
181781
  shouldPlanUseAutoMode: () => shouldPlanUseAutoMode,
181348
181782
  shouldUseSandbox: () => shouldUseSandbox,
@@ -188002,6 +188436,97 @@ var init_streamableHttp = __esm(() => {
188002
188436
  };
188003
188437
  });
188004
188438
 
188439
+ // src/tui/services/mcp/fetchTimeout.ts
188440
+ function getMcpConnectionTimeoutMs() {
188441
+ return parseInt(process.env.MCP_TIMEOUT || "", 10) || 30000;
188442
+ }
188443
+ function bindBodyReadDeadline(response) {
188444
+ const contentType = response.headers?.get("content-type") ?? "";
188445
+ if (contentType.includes("text/event-stream")) {
188446
+ return response;
188447
+ }
188448
+ const rawBody = response.body;
188449
+ if (!rawBody) {
188450
+ return response;
188451
+ }
188452
+ const reader = rawBody.getReader();
188453
+ let deadlineTimer;
188454
+ const deadline = new Promise((_, reject) => {
188455
+ deadlineTimer = setTimeout(() => reject(new DOMException("The operation timed out.", "TimeoutError")), getMcpConnectionTimeoutMs());
188456
+ deadlineTimer.unref?.();
188457
+ });
188458
+ deadline.catch(() => {});
188459
+ const clearDeadline = () => {
188460
+ if (deadlineTimer) {
188461
+ clearTimeout(deadlineTimer);
188462
+ }
188463
+ };
188464
+ const stream = new ReadableStream({
188465
+ async pull(ctrl) {
188466
+ try {
188467
+ const { done, value } = await Promise.race([reader.read(), deadline]);
188468
+ if (done) {
188469
+ clearDeadline();
188470
+ ctrl.close();
188471
+ } else {
188472
+ ctrl.enqueue(value);
188473
+ }
188474
+ } catch (error) {
188475
+ clearDeadline();
188476
+ reader.cancel().catch(() => {});
188477
+ ctrl.error(error);
188478
+ }
188479
+ },
188480
+ cancel(reason) {
188481
+ clearDeadline();
188482
+ return reader.cancel(reason);
188483
+ }
188484
+ });
188485
+ return new Response(stream, {
188486
+ status: response.status,
188487
+ statusText: response.statusText,
188488
+ headers: response.headers
188489
+ });
188490
+ }
188491
+ function wrapFetchWithTimeout(baseFetch) {
188492
+ return async (url, init) => {
188493
+ const method = (init?.method ?? "GET").toUpperCase();
188494
+ if (method === "GET") {
188495
+ return baseFetch(url, init);
188496
+ }
188497
+ const headers = new Headers(init?.headers);
188498
+ if (!headers.has("accept")) {
188499
+ headers.set("accept", MCP_STREAMABLE_HTTP_ACCEPT);
188500
+ }
188501
+ const controller = new AbortController;
188502
+ const timer = setTimeout((c) => c.abort(new DOMException("The operation timed out.", "TimeoutError")), MCP_REQUEST_TIMEOUT_MS, controller);
188503
+ timer.unref?.();
188504
+ const parentSignal = init?.signal;
188505
+ const abort = () => controller.abort(parentSignal?.reason);
188506
+ parentSignal?.addEventListener("abort", abort);
188507
+ if (parentSignal?.aborted) {
188508
+ controller.abort(parentSignal.reason);
188509
+ }
188510
+ const cleanup = () => {
188511
+ clearTimeout(timer);
188512
+ parentSignal?.removeEventListener("abort", abort);
188513
+ };
188514
+ try {
188515
+ const response = await baseFetch(url, {
188516
+ ...init,
188517
+ headers,
188518
+ signal: controller.signal
188519
+ });
188520
+ cleanup();
188521
+ return bindBodyReadDeadline(response);
188522
+ } catch (error) {
188523
+ cleanup();
188524
+ throw error;
188525
+ }
188526
+ };
188527
+ }
188528
+ var MCP_REQUEST_TIMEOUT_MS = 60000, MCP_STREAMABLE_HTTP_ACCEPT = "application/json, text/event-stream";
188529
+
188005
188530
  // node_modules/lodash-es/_baseZipObject.js
188006
188531
  function baseZipObject(props, values, assignFunc) {
188007
188532
  var index = -1, length = props.length, valsLength = values.length, result = {};
@@ -193341,6 +193866,73 @@ var init_browser = __esm(() => {
193341
193866
  init_execFileNoThrow2();
193342
193867
  });
193343
193868
 
193869
+ // src/tui/services/mcp/headersHelper.ts
193870
+ function isMcpServerFromProjectOrLocalSettings(config) {
193871
+ return config.scope === "project" || config.scope === "local";
193872
+ }
193873
+ async function getMcpHeadersFromHelper(serverName, config) {
193874
+ if (!config.headersHelper) {
193875
+ return null;
193876
+ }
193877
+ if ("scope" in config && isMcpServerFromProjectOrLocalSettings(config)) {
193878
+ const isNonInteractive = getIsNonInteractiveSession();
193879
+ const explicitTrust = process.env.ATLAS_TRUST_WORKSPACE === "true";
193880
+ const hasTrust = checkHasTrustDialogAccepted() || isNonInteractive && explicitTrust;
193881
+ if (!hasTrust) {
193882
+ const error = new Error(`Security: headersHelper for MCP server '${serverName}' executed before workspace trust is confirmed. If you see this message, post in ${MACRO.FEEDBACK_CHANNEL}.`);
193883
+ logAntError("MCP headersHelper invoked before trust check", error);
193884
+ return null;
193885
+ }
193886
+ }
193887
+ try {
193888
+ logMCPDebug(serverName, "Executing headersHelper to get dynamic headers");
193889
+ const execResult = await execFileNoThrowWithCwd2("sh", ["-c", config.headersHelper], {
193890
+ timeout: 1e4,
193891
+ env: {
193892
+ ...process.env,
193893
+ ATLAS_MCP_SERVER_NAME: serverName,
193894
+ ATLAS_MCP_SERVER_URL: config.url
193895
+ }
193896
+ });
193897
+ if (execResult.code !== 0 || !execResult.stdout) {
193898
+ throw new Error(`headersHelper for MCP server '${serverName}' did not return a valid value`);
193899
+ }
193900
+ const result = execResult.stdout.trim();
193901
+ const headers = jsonParse2(result);
193902
+ if (typeof headers !== "object" || headers === null || Array.isArray(headers)) {
193903
+ throw new Error(`headersHelper for MCP server '${serverName}' must return a JSON object with string key-value pairs`);
193904
+ }
193905
+ for (const [key, value] of Object.entries(headers)) {
193906
+ if (typeof value !== "string") {
193907
+ throw new Error(`headersHelper for MCP server '${serverName}' returned non-string value for key "${key}": ${typeof value}`);
193908
+ }
193909
+ }
193910
+ logMCPDebug(serverName, `Successfully retrieved ${Object.keys(headers).length} headers from headersHelper`);
193911
+ return headers;
193912
+ } catch (error) {
193913
+ logMCPError(serverName, `Error getting headers from headersHelper: ${errorMessage2(error)}`);
193914
+ logError3(new Error(`Error getting MCP headers from headersHelper for server '${serverName}': ${errorMessage2(error)}`));
193915
+ return null;
193916
+ }
193917
+ }
193918
+ async function getMcpServerHeaders(serverName, config) {
193919
+ const staticHeaders = config.headers || {};
193920
+ const dynamicHeaders = await getMcpHeadersFromHelper(serverName, config) || {};
193921
+ return {
193922
+ ...staticHeaders,
193923
+ ...dynamicHeaders
193924
+ };
193925
+ }
193926
+ var init_headersHelper = __esm(() => {
193927
+ init_bootstrap();
193928
+ init_config6();
193929
+ init_debug();
193930
+ init_errors4();
193931
+ init_execFileNoThrow2();
193932
+ init_log5();
193933
+ init_slowOperations();
193934
+ });
193935
+
193344
193936
  // src/tui/services/mcp/oauthPort.ts
193345
193937
  import { createServer } from "http";
193346
193938
  function buildRedirectUri(port = REDIRECT_PORT_FALLBACK) {
@@ -193848,20 +194440,20 @@ async function writeMcpjsonFile2(config) {
193848
194440
  throw e;
193849
194441
  }
193850
194442
  }
193851
- function getServerCommandArray(config) {
194443
+ function getServerCommandArray2(config) {
193852
194444
  if (config.type !== undefined && config.type !== "stdio") {
193853
194445
  return null;
193854
194446
  }
193855
194447
  const stdioConfig = config;
193856
194448
  return [stdioConfig.command, ...stdioConfig.args ?? []];
193857
194449
  }
193858
- function commandArraysMatch(a, b) {
194450
+ function commandArraysMatch2(a, b) {
193859
194451
  if (a.length !== b.length) {
193860
194452
  return false;
193861
194453
  }
193862
194454
  return a.every((val, idx) => val === b[idx]);
193863
194455
  }
193864
- function getServerUrl(config) {
194456
+ function getServerUrl2(config) {
193865
194457
  return "url" in config ? config.url : null;
193866
194458
  }
193867
194459
  function unwrapCcrProxyUrl(url) {
@@ -193877,11 +194469,11 @@ function unwrapCcrProxyUrl(url) {
193877
194469
  }
193878
194470
  }
193879
194471
  function getMcpServerSignature(config) {
193880
- const cmd = getServerCommandArray(config);
194472
+ const cmd = getServerCommandArray2(config);
193881
194473
  if (cmd) {
193882
194474
  return `stdio:${jsonStringify5(cmd)}`;
193883
194475
  }
193884
- const url = getServerUrl(config);
194476
+ const url = getServerUrl2(config);
193885
194477
  if (url) {
193886
194478
  return `url:${unwrapCcrProxyUrl(url)}`;
193887
194479
  }
@@ -193943,13 +194535,13 @@ function dedupManagedMcpServers(claudeAiServers, manualServers) {
193943
194535
  }
193944
194536
  return { servers, suppressed };
193945
194537
  }
193946
- function urlPatternToRegex(pattern) {
194538
+ function urlPatternToRegex2(pattern) {
193947
194539
  const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
193948
194540
  const regexStr = escaped.replace(/\*/g, ".*");
193949
194541
  return new RegExp(`^${regexStr}$`);
193950
194542
  }
193951
- function urlMatchesPattern(url, pattern) {
193952
- const regex = urlPatternToRegex(pattern);
194543
+ function urlMatchesPattern2(url, pattern) {
194544
+ const regex = urlPatternToRegex2(pattern);
193953
194545
  return regex.test(url);
193954
194546
  }
193955
194547
  function getMcpAllowlistSettings() {
@@ -193972,18 +194564,18 @@ function isMcpServerDenied(serverName, config) {
193972
194564
  }
193973
194565
  }
193974
194566
  if (config) {
193975
- const serverCommand = getServerCommandArray(config);
194567
+ const serverCommand = getServerCommandArray2(config);
193976
194568
  if (serverCommand) {
193977
194569
  for (const entry of settings.deniedMcpServers) {
193978
- if (isMcpServerCommandEntry(entry) && commandArraysMatch(entry.serverCommand, serverCommand)) {
194570
+ if (isMcpServerCommandEntry(entry) && commandArraysMatch2(entry.serverCommand, serverCommand)) {
193979
194571
  return true;
193980
194572
  }
193981
194573
  }
193982
194574
  }
193983
- const serverUrl = getServerUrl(config);
194575
+ const serverUrl = getServerUrl2(config);
193984
194576
  if (serverUrl) {
193985
194577
  for (const entry of settings.deniedMcpServers) {
193986
- if (isMcpServerUrlEntry(entry) && urlMatchesPattern(serverUrl, entry.serverUrl)) {
194578
+ if (isMcpServerUrlEntry(entry) && urlMatchesPattern2(serverUrl, entry.serverUrl)) {
193987
194579
  return true;
193988
194580
  }
193989
194581
  }
@@ -194005,12 +194597,12 @@ function isMcpServerAllowedByPolicy(serverName, config) {
194005
194597
  const hasCommandEntries = settings.allowedMcpServers.some(isMcpServerCommandEntry);
194006
194598
  const hasUrlEntries = settings.allowedMcpServers.some(isMcpServerUrlEntry);
194007
194599
  if (config) {
194008
- const serverCommand = getServerCommandArray(config);
194009
- const serverUrl = getServerUrl(config);
194600
+ const serverCommand = getServerCommandArray2(config);
194601
+ const serverUrl = getServerUrl2(config);
194010
194602
  if (serverCommand) {
194011
194603
  if (hasCommandEntries) {
194012
194604
  for (const entry of settings.allowedMcpServers) {
194013
- if (isMcpServerCommandEntry(entry) && commandArraysMatch(entry.serverCommand, serverCommand)) {
194605
+ if (isMcpServerCommandEntry(entry) && commandArraysMatch2(entry.serverCommand, serverCommand)) {
194014
194606
  return true;
194015
194607
  }
194016
194608
  }
@@ -194026,7 +194618,7 @@ function isMcpServerAllowedByPolicy(serverName, config) {
194026
194618
  } else if (serverUrl) {
194027
194619
  if (hasUrlEntries) {
194028
194620
  for (const entry of settings.allowedMcpServers) {
194029
- if (isMcpServerUrlEntry(entry) && urlMatchesPattern(serverUrl, entry.serverUrl)) {
194621
+ if (isMcpServerUrlEntry(entry) && urlMatchesPattern2(serverUrl, entry.serverUrl)) {
194030
194622
  return true;
194031
194623
  }
194032
194624
  }
@@ -194055,7 +194647,7 @@ function isMcpServerAllowedByPolicy(serverName, config) {
194055
194647
  }
194056
194648
  return false;
194057
194649
  }
194058
- function filterMcpServersByPolicy(configs) {
194650
+ function filterMcpServersByPolicy2(configs) {
194059
194651
  const allowed = {};
194060
194652
  const blocked = [];
194061
194653
  for (const [name, config] of Object.entries(configs)) {
@@ -194507,7 +195099,7 @@ async function getAllMcpConfigs2() {
194507
195099
  }
194508
195100
  const claudeaiPromise = Promise.resolve({});
194509
195101
  const { servers: claudeCodeServers, errors } = await getMcpConfigs({}, claudeaiPromise);
194510
- const { allowed: claudeaiMcpServers } = filterMcpServersByPolicy(await claudeaiPromise);
195102
+ const { allowed: claudeaiMcpServers } = filterMcpServersByPolicy2(await claudeaiPromise);
194511
195103
  const { servers: dedupedClaudeAi } = dedupManagedMcpServers(claudeaiMcpServers, claudeCodeServers);
194512
195104
  const servers = Object.assign({}, dedupedClaudeAi, claudeCodeServers);
194513
195105
  return { servers, errors };
@@ -194612,6 +195204,9 @@ function parseMcpConfigFromFilePath(params) {
194612
195204
  ]
194613
195205
  };
194614
195206
  }
195207
+ if (!configContent.trim()) {
195208
+ return { config: { mcpServers: {} }, errors: [] };
195209
+ }
194615
195210
  const parsedJson = safeParseJSON3(configContent);
194616
195211
  if (!parsedJson) {
194617
195212
  logForDebugging3(`MCP config is not valid JSON: ${filePath} (scope=${scope}, length=${configContent.length}, first100=${jsonStringify5(configContent.slice(0, 100))})`, { level: "error" });
@@ -194631,6 +195226,9 @@ function parseMcpConfigFromFilePath(params) {
194631
195226
  ]
194632
195227
  };
194633
195228
  }
195229
+ if (typeof parsedJson === "object" && parsedJson !== null && !Array.isArray(parsedJson) && Object.keys(parsedJson).length === 0) {
195230
+ return { config: { mcpServers: {} }, errors: [] };
195231
+ }
194634
195232
  return parseMcpConfig({
194635
195233
  configObject: parsedJson,
194636
195234
  expandVars,
@@ -194761,11 +195359,11 @@ function hashMcpConfig(config) {
194761
195359
  });
194762
195360
  return createHash4("sha256").update(stable).digest("hex").slice(0, 16);
194763
195361
  }
194764
- function excludeStalePluginClients(mcp, configs) {
195362
+ function excludeStalePluginClients(mcp, configs, opts) {
194765
195363
  const stale = mcp.clients.filter((c) => {
194766
195364
  const fresh = configs[c.name];
194767
195365
  if (!fresh)
194768
- return c.config.scope === "dynamic";
195366
+ return opts?.absentIsStale || c.config.scope === "dynamic";
194769
195367
  return hashMcpConfig(c.config) !== hashMcpConfig(fresh);
194770
195368
  });
194771
195369
  if (stale.length === 0) {
@@ -195561,6 +196159,53 @@ function createAuthFetch() {
195561
196159
  }
195562
196160
  };
195563
196161
  }
196162
+ async function resolveConfiguredMcpHeaders(serverName, serverConfig) {
196163
+ try {
196164
+ return await getMcpServerHeaders(serverName, serverConfig);
196165
+ } catch (error) {
196166
+ logMCPDebug(serverName, `Failed to resolve configured headers for OAuth: ${errorMessage2(error)}`);
196167
+ return {};
196168
+ }
196169
+ }
196170
+ function headersToRecord2(headers) {
196171
+ const out = {};
196172
+ if (!headers)
196173
+ return out;
196174
+ if (headers instanceof Headers) {
196175
+ headers.forEach((v, k) => {
196176
+ out[k] = v;
196177
+ });
196178
+ return out;
196179
+ }
196180
+ if (Array.isArray(headers)) {
196181
+ for (const [k, v] of headers)
196182
+ out[k] = v;
196183
+ return out;
196184
+ }
196185
+ if (typeof headers === "object") {
196186
+ for (const [k, v] of Object.entries(headers)) {
196187
+ out[k] = String(v);
196188
+ }
196189
+ }
196190
+ return out;
196191
+ }
196192
+ function mergeConfiguredHeaders(fetchLike, configured) {
196193
+ if (Object.keys(configured).length === 0)
196194
+ return fetchLike;
196195
+ return (url, init) => {
196196
+ const requestHeaders = headersToRecord2(init?.headers);
196197
+ const requestKeys = new Set(Object.keys(requestHeaders).map((k) => k.toLowerCase()));
196198
+ const configuredNotOverridden = Object.fromEntries(Object.entries(configured).filter(([k]) => !requestKeys.has(k.toLowerCase())));
196199
+ return fetchLike(url, {
196200
+ ...init,
196201
+ headers: { ...configuredNotOverridden, ...requestHeaders }
196202
+ });
196203
+ };
196204
+ }
196205
+ async function withConfiguredHeaders(fetchLike, serverName, serverConfig) {
196206
+ const configured = await resolveConfiguredMcpHeaders(serverName, serverConfig);
196207
+ return mergeConfiguredHeaders(fetchLike, configured);
196208
+ }
195564
196209
  async function fetchAuthServerMetadata(serverName, serverUrl, configuredMetadataUrl, fetchFn, resourceMetadataUrl) {
195565
196210
  if (configuredMetadataUrl) {
195566
196211
  if (!configuredMetadataUrl.startsWith("https://")) {
@@ -195619,12 +196264,14 @@ async function revokeToken({
195619
196264
  clientId,
195620
196265
  clientSecret,
195621
196266
  accessToken,
195622
- authMethod = "client_secret_basic"
196267
+ authMethod = "client_secret_basic",
196268
+ extraHeaders
195623
196269
  }) {
195624
196270
  const params = new URLSearchParams;
195625
196271
  params.set("token", token);
195626
196272
  params.set("token_type_hint", tokenTypeHint);
195627
196273
  const headers = {
196274
+ ...extraHeaders ?? {},
195628
196275
  "Content-Type": "application/x-www-form-urlencoded"
195629
196276
  };
195630
196277
  if (clientId && clientSecret) {
@@ -195667,7 +196314,8 @@ async function revokeServerTokens(serverName, serverConfig, { preserveStepUpStat
195667
196314
  if (tokenData?.accessToken || tokenData?.refreshToken) {
195668
196315
  try {
195669
196316
  const asUrl = tokenData.discoveryState?.authorizationServerUrl ?? serverConfig.url;
195670
- const metadata = await fetchAuthServerMetadata(serverName, asUrl, serverConfig.oauth?.authServerMetadataUrl);
196317
+ const configuredHeaders = await resolveConfiguredMcpHeaders(serverName, serverConfig);
196318
+ const metadata = await fetchAuthServerMetadata(serverName, asUrl, serverConfig.oauth?.authServerMetadataUrl, mergeConfiguredHeaders(createAuthFetch(), configuredHeaders));
195671
196319
  if (!metadata) {
195672
196320
  logMCPDebug(serverName, "No OAuth metadata found");
195673
196321
  } else {
@@ -195689,7 +196337,8 @@ async function revokeServerTokens(serverName, serverConfig, { preserveStepUpStat
195689
196337
  clientId: tokenData.clientId,
195690
196338
  clientSecret: tokenData.clientSecret,
195691
196339
  accessToken: tokenData.accessToken,
195692
- authMethod
196340
+ authMethod,
196341
+ extraHeaders: configuredHeaders
195693
196342
  });
195694
196343
  } catch (error) {
195695
196344
  logMCPDebug(serverName, `Failed to revoke refresh token: ${errorMessage2(error)}`);
@@ -195705,7 +196354,8 @@ async function revokeServerTokens(serverName, serverConfig, { preserveStepUpStat
195705
196354
  clientId: tokenData.clientId,
195706
196355
  clientSecret: tokenData.clientSecret,
195707
196356
  accessToken: tokenData.accessToken,
195708
- authMethod
196357
+ authMethod,
196358
+ extraHeaders: configuredHeaders
195709
196359
  });
195710
196360
  } catch (error) {
195711
196361
  logMCPDebug(serverName, `Failed to revoke access token: ${errorMessage2(error)}`);
@@ -195898,8 +196548,9 @@ async function performMCPOAuthFlow(serverName, serverConfig, onAuthorizationUrl,
195898
196548
  const redirectUri = buildRedirectUri(port);
195899
196549
  logMCPDebug(serverName, `Using redirect port: ${port}${configuredCallbackPort ? " (from config)" : ""}`);
195900
196550
  const provider = new ClaudeAuthProvider(serverName, serverConfig, redirectUri, true, onAuthorizationUrl, options?.skipBrowserOpen);
196551
+ const oauthFetch = await withConfiguredHeaders(createAuthFetch(), serverName, serverConfig);
195901
196552
  try {
195902
- const metadata = await fetchAuthServerMetadata(serverName, serverConfig.url, serverConfig.oauth?.authServerMetadataUrl, undefined, wwwAuthParams.resourceMetadataUrl);
196553
+ const metadata = await fetchAuthServerMetadata(serverName, serverConfig.url, serverConfig.oauth?.authServerMetadataUrl, oauthFetch, wwwAuthParams.resourceMetadataUrl);
195903
196554
  if (metadata) {
195904
196555
  provider.setMetadata(metadata);
195905
196556
  logMCPDebug(serverName, `Fetched OAuth metadata with scope: ${getScopeFromMetadata(metadata) || "NONE"}`);
@@ -196035,7 +196686,8 @@ async function performMCPOAuthFlow(serverName, serverConfig, onAuthorizationUrl,
196035
196686
  const result = await auth(provider, {
196036
196687
  serverUrl: serverConfig.url,
196037
196688
  scope: wwwAuthParams.scope,
196038
- resourceMetadataUrl: wwwAuthParams.resourceMetadataUrl
196689
+ resourceMetadataUrl: wwwAuthParams.resourceMetadataUrl,
196690
+ fetchFn: oauthFetch
196039
196691
  });
196040
196692
  logMCPDebug(serverName, `Initial auth result: ${result}`);
196041
196693
  if (result !== "REDIRECT") {
@@ -196059,7 +196711,8 @@ async function performMCPOAuthFlow(serverName, serverConfig, onAuthorizationUrl,
196059
196711
  const result = await auth(provider, {
196060
196712
  serverUrl: serverConfig.url,
196061
196713
  authorizationCode,
196062
- resourceMetadataUrl: wwwAuthParams.resourceMetadataUrl
196714
+ resourceMetadataUrl: wwwAuthParams.resourceMetadataUrl,
196715
+ fetchFn: oauthFetch
196063
196716
  });
196064
196717
  logMCPDebug(serverName, `Auth result: ${result}`);
196065
196718
  if (result === "AUTHORIZED") {
@@ -196566,7 +197219,7 @@ class ClaudeAuthProvider {
196566
197219
  if (metadataUrl) {
196567
197220
  logMCPDebug(this.serverName, `Fetching metadata from configured URL: ${metadataUrl}`);
196568
197221
  try {
196569
- const metadata = await fetchAuthServerMetadata(this.serverName, this.serverConfig.url, metadataUrl);
197222
+ const metadata = await fetchAuthServerMetadata(this.serverName, this.serverConfig.url, metadataUrl, await withConfiguredHeaders(createAuthFetch(), this.serverName, this.serverConfig));
196570
197223
  if (metadata) {
196571
197224
  return {
196572
197225
  authorizationServerUrl: metadata.issuer,
@@ -196651,7 +197304,7 @@ class ClaudeAuthProvider {
196651
197304
  for (let attempt = 1;attempt <= MAX_ATTEMPTS; attempt++) {
196652
197305
  try {
196653
197306
  logMCPDebug(this.serverName, `Starting token refresh`);
196654
- const authFetch = createAuthFetch();
197307
+ const authFetch = await withConfiguredHeaders(createAuthFetch(), this.serverName, this.serverConfig);
196655
197308
  let metadata = this._metadata;
196656
197309
  if (!metadata) {
196657
197310
  const cached = await this.discoveryState();
@@ -196827,6 +197480,7 @@ var init_auth3 = __esm(() => {
196827
197480
  init_secureStorage();
196828
197481
  init_macOsKeychainHelpers();
196829
197482
  init_slowOperations();
197483
+ init_headersHelper();
196830
197484
  init_oauthPort();
196831
197485
  init_utils6();
196832
197486
  init_xaa();
@@ -200822,10 +201476,10 @@ function parseProxyResponse(socket) {
200822
201476
  read();
200823
201477
  });
200824
201478
  }
200825
- var import_debug52, debug;
201479
+ var import_debug53, debug;
200826
201480
  var init_parse_proxy_response = __esm(() => {
200827
- import_debug52 = __toESM(require_src(), 1);
200828
- debug = import_debug52.default("https-proxy-agent:parse-proxy-response");
201481
+ import_debug53 = __toESM(require_src(), 1);
201482
+ debug = import_debug53.default("https-proxy-agent:parse-proxy-response");
200829
201483
  });
200830
201484
 
200831
201485
  // node_modules/proxy-agent-negotiate/dist/index.js
@@ -200878,7 +201532,7 @@ function omit2(obj, ...keys) {
200878
201532
  }
200879
201533
  return ret;
200880
201534
  }
200881
- var import_debug53, debug2, setServernameFromNonIpHost = (options) => {
201535
+ var import_debug54, debug2, setServernameFromNonIpHost = (options) => {
200882
201536
  if (options.servername === undefined && options.host && !net2.isIP(options.host)) {
200883
201537
  return {
200884
201538
  ...options,
@@ -200890,8 +201544,8 @@ var import_debug53, debug2, setServernameFromNonIpHost = (options) => {
200890
201544
  var init_dist7 = __esm(() => {
200891
201545
  init_dist6();
200892
201546
  init_parse_proxy_response();
200893
- import_debug53 = __toESM(require_src(), 1);
200894
- debug2 = import_debug53.default("https-proxy-agent");
201547
+ import_debug54 = __toESM(require_src(), 1);
201548
+ debug2 = import_debug54.default("https-proxy-agent");
200895
201549
  HttpsProxyAgent2 = class HttpsProxyAgent2 extends Agent2 {
200896
201550
  constructor(proxy, opts) {
200897
201551
  super(opts);
@@ -201952,73 +202606,6 @@ var init_classifyForCollapse = __esm(() => {
201952
202606
  "resources_list"
201953
202607
  ]);
201954
202608
  });
201955
-
201956
- // src/tui/services/mcp/headersHelper.ts
201957
- function isMcpServerFromProjectOrLocalSettings(config) {
201958
- return config.scope === "project" || config.scope === "local";
201959
- }
201960
- async function getMcpHeadersFromHelper(serverName, config) {
201961
- if (!config.headersHelper) {
201962
- return null;
201963
- }
201964
- if ("scope" in config && isMcpServerFromProjectOrLocalSettings(config)) {
201965
- const isNonInteractive = getIsNonInteractiveSession();
201966
- const explicitTrust = process.env.ATLAS_TRUST_WORKSPACE === "true";
201967
- const hasTrust = checkHasTrustDialogAccepted() || isNonInteractive && explicitTrust;
201968
- if (!hasTrust) {
201969
- const error = new Error(`Security: headersHelper for MCP server '${serverName}' executed before workspace trust is confirmed. If you see this message, post in ${MACRO.FEEDBACK_CHANNEL}.`);
201970
- logAntError("MCP headersHelper invoked before trust check", error);
201971
- return null;
201972
- }
201973
- }
201974
- try {
201975
- logMCPDebug(serverName, "Executing headersHelper to get dynamic headers");
201976
- const execResult = await execFileNoThrowWithCwd2("sh", ["-c", config.headersHelper], {
201977
- timeout: 1e4,
201978
- env: {
201979
- ...process.env,
201980
- ATLAS_MCP_SERVER_NAME: serverName,
201981
- ATLAS_MCP_SERVER_URL: config.url
201982
- }
201983
- });
201984
- if (execResult.code !== 0 || !execResult.stdout) {
201985
- throw new Error(`headersHelper for MCP server '${serverName}' did not return a valid value`);
201986
- }
201987
- const result = execResult.stdout.trim();
201988
- const headers = jsonParse2(result);
201989
- if (typeof headers !== "object" || headers === null || Array.isArray(headers)) {
201990
- throw new Error(`headersHelper for MCP server '${serverName}' must return a JSON object with string key-value pairs`);
201991
- }
201992
- for (const [key, value] of Object.entries(headers)) {
201993
- if (typeof value !== "string") {
201994
- throw new Error(`headersHelper for MCP server '${serverName}' returned non-string value for key "${key}": ${typeof value}`);
201995
- }
201996
- }
201997
- logMCPDebug(serverName, `Successfully retrieved ${Object.keys(headers).length} headers from headersHelper`);
201998
- return headers;
201999
- } catch (error) {
202000
- logMCPError(serverName, `Error getting headers from headersHelper: ${errorMessage2(error)}`);
202001
- logError3(new Error(`Error getting MCP headers from headersHelper for server '${serverName}': ${errorMessage2(error)}`));
202002
- return null;
202003
- }
202004
- }
202005
- async function getMcpServerHeaders(serverName, config) {
202006
- const staticHeaders = config.headers || {};
202007
- const dynamicHeaders = await getMcpHeadersFromHelper(serverName, config) || {};
202008
- return {
202009
- ...staticHeaders,
202010
- ...dynamicHeaders
202011
- };
202012
- }
202013
- var init_headersHelper = __esm(() => {
202014
- init_bootstrap();
202015
- init_config6();
202016
- init_debug();
202017
- init_errors4();
202018
- init_execFileNoThrow2();
202019
- init_log5();
202020
- init_slowOperations();
202021
- });
202022
202609
  // src/tui/skills/mcpSkills.ts
202023
202610
  var exports_mcpSkills = {};
202024
202611
  __export(exports_mcpSkills, {
@@ -209465,6 +210052,11 @@ function isMcpSessionExpiredError(error) {
209465
210052
  }
209466
210053
  return error.message.includes('"code":-32001') || error.message.includes('"code": -32001');
209467
210054
  }
210055
+ function truncateMcpDescriptionText(text) {
210056
+ if (!text)
210057
+ return text;
210058
+ return text.length > MAX_MCP_DESCRIPTION_LENGTH ? text.slice(0, MAX_MCP_DESCRIPTION_LENGTH) + "… [truncated]" : text;
210059
+ }
209468
210060
  function getMcpToolTimeoutMs() {
209469
210061
  return parseInt(process.env.MCP_TOOL_TIMEOUT || "", 10) || DEFAULT_MCP_TOOL_TIMEOUT_MS;
209470
210062
  }
@@ -209513,46 +210105,6 @@ async function createNodeWsClient(url, options) {
209513
210105
  const WS = wrapper_default;
209514
210106
  return new WS(url, ["mcp"], options);
209515
210107
  }
209516
- function getConnectionTimeoutMs2() {
209517
- return parseInt(process.env.MCP_TIMEOUT || "", 10) || 30000;
209518
- }
209519
- function wrapFetchWithTimeout(baseFetch) {
209520
- return async (url, init) => {
209521
- const method = (init?.method ?? "GET").toUpperCase();
209522
- if (method === "GET") {
209523
- return baseFetch(url, init);
209524
- }
209525
- const headers = new Headers(init?.headers);
209526
- if (!headers.has("accept")) {
209527
- headers.set("accept", MCP_STREAMABLE_HTTP_ACCEPT);
209528
- }
209529
- const controller = new AbortController;
209530
- const timer = setTimeout((c) => c.abort(new DOMException("The operation timed out.", "TimeoutError")), MCP_REQUEST_TIMEOUT_MS, controller);
209531
- timer.unref?.();
209532
- const parentSignal = init?.signal;
209533
- const abort = () => controller.abort(parentSignal?.reason);
209534
- parentSignal?.addEventListener("abort", abort);
209535
- if (parentSignal?.aborted) {
209536
- controller.abort(parentSignal.reason);
209537
- }
209538
- const cleanup = () => {
209539
- clearTimeout(timer);
209540
- parentSignal?.removeEventListener("abort", abort);
209541
- };
209542
- try {
209543
- const response = await baseFetch(url, {
209544
- ...init,
209545
- headers,
209546
- signal: controller.signal
209547
- });
209548
- cleanup();
209549
- return response;
209550
- } catch (error) {
209551
- cleanup();
209552
- throw error;
209553
- }
209554
- };
209555
- }
209556
210108
  function getMcpServerConnectionBatchSize() {
209557
210109
  return parseInt(process.env.MCP_SERVER_CONNECTION_BATCH_SIZE || "", 10) || 3;
209558
210110
  }
@@ -210202,7 +210754,7 @@ function extractToolUseId(message) {
210202
210754
  }
210203
210755
  return message.message.content[0].id;
210204
210756
  }
210205
- var fetchMcpSkillsForClient2, McpAuthError, McpSessionExpiredError, McpToolCallError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, DEFAULT_MCP_TOOL_TIMEOUT_MS = 1e8, MAX_MCP_DESCRIPTION_LENGTH = 2048, computerUseWrapper, isComputerUseMCPServer2, MCP_AUTH_CACHE_TTL_MS, authCachePromise = null, writeChain, IMAGE_MIME_TYPES, MCP_REQUEST_TIMEOUT_MS = 60000, MCP_STREAMABLE_HTTP_ACCEPT = "application/json, text/event-stream", ALLOWED_IDE_TOOLS, connectToServer, MCP_FETCH_CACHE_SIZE2 = 20, fetchToolsForClient2, fetchResourcesForClient2, fetchCommandsForClient2;
210757
+ var fetchMcpSkillsForClient2, McpAuthError, McpSessionExpiredError, McpToolCallError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, DEFAULT_MCP_TOOL_TIMEOUT_MS = 1e8, MAX_MCP_DESCRIPTION_LENGTH = 4096, computerUseWrapper, isComputerUseMCPServer2, MCP_AUTH_CACHE_TTL_MS, authCachePromise = null, writeChain, IMAGE_MIME_TYPES, ALLOWED_IDE_TOOLS, connectToServer, MCP_FETCH_CACHE_SIZE2 = 20, fetchToolsForClient2, fetchResourcesForClient2, fetchCommandsForClient2;
210206
210758
  var init_client4 = __esm(() => {
210207
210759
  init_shared();
210208
210760
  init_client3();
@@ -210494,7 +211046,7 @@ var init_client4 = __esm(() => {
210494
211046
  ]
210495
211047
  };
210496
211048
  });
210497
- logMCPDebug(name, `Starting connection with timeout of ${getConnectionTimeoutMs2()}ms`);
211049
+ logMCPDebug(name, `Starting connection with timeout of ${getMcpConnectionTimeoutMs()}ms`);
210498
211050
  if (serverRef.type === "http") {
210499
211051
  logMCPDebug(name, `Testing basic HTTP connectivity to ${serverRef.url}`);
210500
211052
  try {
@@ -210511,13 +211063,13 @@ var init_client4 = __esm(() => {
210511
211063
  const timeoutPromise = new Promise((_, reject) => {
210512
211064
  const timeoutId = setTimeout(() => {
210513
211065
  const elapsed = Date.now() - connectStartTime;
210514
- logMCPDebug(name, `Connection timeout triggered after ${elapsed}ms (limit: ${getConnectionTimeoutMs2()}ms)`);
211066
+ logMCPDebug(name, `Connection timeout triggered after ${elapsed}ms (limit: ${getMcpConnectionTimeoutMs()}ms)`);
210515
211067
  if (inProcessServer) {
210516
211068
  inProcessServer.close().catch(() => {});
210517
211069
  }
210518
211070
  transport.close().catch(() => {});
210519
- reject(new TelemetrySafeError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS(`MCP server "${name}" connection timed out after ${getConnectionTimeoutMs2()}ms`, "MCP connection timeout"));
210520
- }, getConnectionTimeoutMs2());
211071
+ reject(new TelemetrySafeError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS(`MCP server "${name}" connection timed out after ${getMcpConnectionTimeoutMs()}ms`, "MCP connection timeout"));
211072
+ }, getMcpConnectionTimeoutMs());
210521
211073
  connectPromise.then(() => {
210522
211074
  clearTimeout(timeoutId);
210523
211075
  }, (_error) => {
@@ -210565,9 +211117,8 @@ var init_client4 = __esm(() => {
210565
211117
  const capabilities = client.getServerCapabilities();
210566
211118
  const serverVersion = client.getServerVersion();
210567
211119
  const rawInstructions = client.getInstructions();
210568
- let instructions = rawInstructions;
210569
- if (rawInstructions && rawInstructions.length > MAX_MCP_DESCRIPTION_LENGTH) {
210570
- instructions = rawInstructions.slice(0, MAX_MCP_DESCRIPTION_LENGTH) + "… [truncated]";
211120
+ const instructions = truncateMcpDescriptionText(rawInstructions);
211121
+ if (instructions !== rawInstructions) {
210571
211122
  logMCPDebug(name, `Server instructions truncated from ${rawInstructions.length} to ${MAX_MCP_DESCRIPTION_LENGTH} chars`);
210572
211123
  }
210573
211124
  logMCPDebug(name, `Connection established with capabilities: ${jsonStringify5({
@@ -210855,8 +211406,7 @@ var init_client4 = __esm(() => {
210855
211406
  return tool.description ?? "";
210856
211407
  },
210857
211408
  async prompt() {
210858
- const desc = tool.description ?? "";
210859
- return desc.length > MAX_MCP_DESCRIPTION_LENGTH ? desc.slice(0, MAX_MCP_DESCRIPTION_LENGTH) + "… [truncated]" : desc;
211409
+ return truncateMcpDescriptionText(tool.description ?? "");
210860
211410
  },
210861
211411
  isConcurrencySafe() {
210862
211412
  return tool.annotations?.readOnlyHint ?? false;
@@ -263542,6 +264092,10 @@ function CompactSummary(t0) {
263542
264092
  description: "expand history",
263543
264093
  parens: true
263544
264094
  }, undefined, false, undefined, this)
264095
+ }, undefined, false, undefined, this),
264096
+ /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
264097
+ dimColor: true,
264098
+ children: "Summary is saved to the session transcript and restored on resume"
263545
264099
  }, undefined, false, undefined, this)
263546
264100
  ]
263547
264101
  }, undefined, true, undefined, this)
@@ -263634,14 +264188,20 @@ function CompactSummary(t0) {
263634
264188
  t2,
263635
264189
  /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedBox_default, {
263636
264190
  flexDirection: "column",
263637
- children: /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
263638
- bold: true,
263639
- children: [
263640
- "Compact summary",
263641
- t3
263642
- ]
263643
- }, undefined, true, undefined, this)
263644
- }, undefined, false, undefined, this)
264191
+ children: [
264192
+ /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
264193
+ bold: true,
264194
+ children: [
264195
+ "Compact summary",
264196
+ t3
264197
+ ]
264198
+ }, undefined, true, undefined, this),
264199
+ /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
264200
+ dimColor: true,
264201
+ children: "Summary is saved to the session transcript and restored on resume"
264202
+ }, undefined, false, undefined, this)
264203
+ ]
264204
+ }, undefined, true, undefined, this)
263645
264205
  ]
263646
264206
  }, undefined, true, undefined, this);
263647
264207
  $[16] = t3;
@@ -274293,6 +274853,7 @@ async function* runAgent2({
274293
274853
  getAppState: () => agentToolUseContext.getAppState(),
274294
274854
  querySource,
274295
274855
  maxTurns: effectiveMaxTurns,
274856
+ ...agentDefinition.autoCompactWindow !== undefined ? { autoCompactWindowOverride: agentDefinition.autoCompactWindow } : {},
274296
274857
  signal: agentAbortController.signal
274297
274858
  });
274298
274859
  const stream = queryEngineLoopStream({
@@ -276148,6 +276709,15 @@ function filterToolsForAgent2({
276148
276709
  function computeChildSpawnDepth2(parentOptions) {
276149
276710
  return (parentOptions?.spawnDepth ?? 0) + 1;
276150
276711
  }
276712
+ function resolveMcpServerDomainTools2(toolName, available) {
276713
+ if (typeof toolName !== "string")
276714
+ return null;
276715
+ const info = mcpInfoFromString3(toolName);
276716
+ if (!info || info.toolName !== undefined)
276717
+ return null;
276718
+ const prefix = getMcpPrefix3(info.serverName);
276719
+ return available.filter((t) => t.name.startsWith(prefix));
276720
+ }
276151
276721
  function resolveAgentTools2(agentDefinition, availableTools, isAsync = false, isMainThread = false, allowFanOut = false) {
276152
276722
  const {
276153
276723
  tools: agentTools,
@@ -276204,7 +276774,18 @@ function resolveAgentTools2(agentDefinition, availableTools, isAsync = false, is
276204
276774
  resolvedToolsSet.add(tool);
276205
276775
  }
276206
276776
  } else {
276207
- invalidTools.push(toolSpec);
276777
+ const domain = resolveMcpServerDomainTools2(toolName, allowedAvailableTools);
276778
+ if (domain && domain.length > 0) {
276779
+ validTools.push(toolSpec);
276780
+ for (const t of domain) {
276781
+ if (!resolvedToolsSet.has(t)) {
276782
+ resolved.push(t);
276783
+ resolvedToolsSet.add(t);
276784
+ }
276785
+ }
276786
+ } else {
276787
+ invalidTools.push(toolSpec);
276788
+ }
276208
276789
  }
276209
276790
  }
276210
276791
  return {
@@ -276461,6 +277042,7 @@ var init_agentToolUtils2 = __esm(() => {
276461
277042
  init_errors4();
276462
277043
  init_messages3();
276463
277044
  init_permissionRuleParser2();
277045
+ init_mcpStringUtils();
276464
277046
  init_yoloClassifier();
276465
277047
  init_sdkProgress();
276466
277048
  init_teammateContext3();
@@ -321484,14 +322066,19 @@ function buildAgentLoopParams(m) {
321484
322066
  const resolved = pool.length > 0 ? resolveModel(pool[0]) : undefined;
321485
322067
  const toolList = m.tools;
321486
322068
  const countTokens = (msgs) => modelProvider.countTokens(role, sessionModel, msgs, toolList);
321487
- const mergedAutoCompact = mergeAutoCompactOverrides(getAutoCompactEnvOverrides(), getInitialSettings2().autoCompactWindow, mainLoopModel);
322069
+ const envAutoCompact = getAutoCompactEnvOverrides();
322070
+ const mergedAutoCompact = mergeAutoCompactOverrides(envAutoCompact, getInitialSettings2().autoCompactWindow, mainLoopModel);
322071
+ const autoCompactWindowOverride = envAutoCompact.windowOverride !== undefined ? mergedAutoCompact.windowOverride : m.autoCompactWindowOverride ?? mergedAutoCompact.windowOverride;
321488
322072
  const autoCompact = {
321489
322073
  contextWindow: resolved?.contextWindow ?? HARD_DEFAULT_CONTEXT_WINDOW,
321490
322074
  maxOutputTokens: resolved?.maxTokens,
321491
322075
  countTokens,
321492
322076
  enabled: mergedAutoCompact.autoCompactDisabled ? false : undefined,
321493
322077
  pctOverride: mergedAutoCompact.pctOverride,
321494
- windowOverride: mergedAutoCompact.windowOverride,
322078
+ windowOverride: autoCompactWindowOverride,
322079
+ ...m.toolUseContext.options?.thinkingConfig?.type === "enabled" ? {
322080
+ thinkingBudgetTokens: m.toolUseContext.options.thinkingConfig.budgetTokens
322081
+ } : {},
321495
322082
  compact: createAutoCompactCompact({
321496
322083
  trimmedSummarize: async (compactMsgs, prompt) => {
321497
322084
  const resp = await modelProvider.chat({
@@ -321573,7 +322160,8 @@ function buildAgentLoopParams(m) {
321573
322160
  }
321574
322161
  },
321575
322162
  systemPrompt: asSystemPrompt(appendSystemContext(m.systemPrompt, systemContext)),
321576
- effortValue: m.effort !== undefined ? String(m.effort) : undefined
322163
+ effortValue: m.effort !== undefined ? String(m.effort) : undefined,
322164
+ refreshRoundContext: m.refreshRoundContext
321577
322165
  };
321578
322166
  const unboundedTurns = m.unboundedTurns ?? m.maxTurns === undefined;
321579
322167
  const args = {
@@ -322142,7 +322730,8 @@ function getDefaultAppState() {
322142
322730
  tools: [],
322143
322731
  commands: [],
322144
322732
  resources: {},
322145
- pluginReconnectKey: 0
322733
+ pluginReconnectKey: 0,
322734
+ cwdReconnectKey: 0
322146
322735
  },
322147
322736
  plugins: {
322148
322737
  enabled: [],
@@ -347883,7 +348472,8 @@ async function clearConversation({
347883
348472
  tools: [],
347884
348473
  commands: [],
347885
348474
  resources: {},
347886
- pluginReconnectKey: prev.mcp.pluginReconnectKey
348475
+ pluginReconnectKey: prev.mcp.pluginReconnectKey,
348476
+ cwdReconnectKey: prev.mcp.cwdReconnectKey
347887
348477
  }
347888
348478
  };
347889
348479
  });
@@ -349148,8 +349738,7 @@ __export(exports_autocompact, {
349148
349738
  call: () => call9
349149
349739
  });
349150
349740
  function currentTierFor(raw, model) {
349151
- const map = normalizeAutoCompactWindowSetting(raw);
349152
- return map[model] ?? map.default;
349741
+ return lookupAutoCompactWindowSetting(normalizeAutoCompactWindowSetting(raw), model);
349153
349742
  }
349154
349743
  function currentToOptionValue(setting) {
349155
349744
  if (!setting || setting.kind === "auto")
@@ -354956,6 +355545,21 @@ function Config({
354956
355545
  }));
354957
355546
  }
354958
355547
  },
355548
+ {
355549
+ id: "idleCompaction",
355550
+ label: "Idle compaction",
355551
+ value: settingsData?.idleCompaction ?? true,
355552
+ type: "boolean",
355553
+ onChange(idleCompaction) {
355554
+ updateSettingsForSource2("localSettings", {
355555
+ idleCompaction
355556
+ });
355557
+ setSettingsData((prev_3b) => ({
355558
+ ...prev_3b,
355559
+ idleCompaction
355560
+ }));
355561
+ }
355562
+ },
354959
355563
  {
354960
355564
  id: "prefersReducedMotion",
354961
355565
  label: "Reduce motion",
@@ -355592,6 +356196,7 @@ function Config({
355592
356196
  const il = initialLocalSettings;
355593
356197
  updateSettingsForSource2("localSettings", {
355594
356198
  spinnerTipsEnabled: il?.spinnerTipsEnabled,
356199
+ idleCompaction: il?.idleCompaction,
355595
356200
  prefersReducedMotion: il?.prefersReducedMotion,
355596
356201
  outputStyle: il?.outputStyle
355597
356202
  });
@@ -369257,7 +369862,9 @@ function useManageMCPConnections(dynamicMcpConfig, isStrictMcpConfig = false) {
369257
369862
  const store = useAppStateStore();
369258
369863
  const _authVersion = useAppState((s) => s.authVersion);
369259
369864
  const _pluginReconnectKey = useAppState((s) => s.mcp.pluginReconnectKey);
369865
+ const _cwdReconnectKey = useAppState((s) => s.mcp.cwdReconnectKey);
369260
369866
  const setAppState = useSetAppState();
369867
+ const lastCwdRef = import_react110.useRef(null);
369261
369868
  const reconnectTimersRef = import_react110.useRef(new Map);
369262
369869
  const mcpFailureTrackerRef = import_react110.useRef(null);
369263
369870
  const notifyMcpConnectionFailure = import_react110.useCallback((serverName, error) => {
@@ -369484,9 +370091,12 @@ function useManageMCPConnections(dynamicMcpConfig, isStrictMcpConfig = false) {
369484
370091
  async function initializeServersAsPending() {
369485
370092
  const { servers: existingConfigs, errors: mcpErrors } = isStrictMcpConfig ? { servers: {}, errors: [] } : await getMcpConfigs(dynamicMcpConfig);
369486
370093
  const configs = { ...existingConfigs, ...dynamicMcpConfig };
370094
+ const currentCwd = getCwd();
370095
+ const cwdChanged = lastCwdRef.current !== null && lastCwdRef.current !== currentCwd;
370096
+ lastCwdRef.current = currentCwd;
369487
370097
  addErrorsToAppState(setAppState, mcpErrors);
369488
370098
  setAppState((prevState) => {
369489
- const { stale, ...mcpWithoutStale } = excludeStalePluginClients(prevState.mcp, configs);
370099
+ const { stale, ...mcpWithoutStale } = excludeStalePluginClients(prevState.mcp, configs, { absentIsStale: cwdChanged });
369490
370100
  for (const s of stale) {
369491
370101
  const timer = reconnectTimersRef.current.get(s.name);
369492
370102
  if (timer) {
@@ -369525,7 +370135,8 @@ function useManageMCPConnections(dynamicMcpConfig, isStrictMcpConfig = false) {
369525
370135
  dynamicMcpConfig,
369526
370136
  setAppState,
369527
370137
  sessionId,
369528
- _pluginReconnectKey
370138
+ _pluginReconnectKey,
370139
+ _cwdReconnectKey
369529
370140
  ]);
369530
370141
  import_react110.useEffect(() => {
369531
370142
  let cancelled = false;
@@ -369542,7 +370153,7 @@ function useManageMCPConnections(dynamicMcpConfig, isStrictMcpConfig = false) {
369542
370153
  });
369543
370154
  let claudeaiConfigs = {};
369544
370155
  if (!isStrictMcpConfig) {
369545
- claudeaiConfigs = filterMcpServersByPolicy(await claudeaiPromise).allowed;
370156
+ claudeaiConfigs = filterMcpServersByPolicy2(await claudeaiPromise).allowed;
369546
370157
  if (cancelled)
369547
370158
  return;
369548
370159
  if (Object.keys(claudeaiConfigs).length > 0) {
@@ -369608,7 +370219,8 @@ function useManageMCPConnections(dynamicMcpConfig, isStrictMcpConfig = false) {
369608
370219
  setAppState,
369609
370220
  _authVersion,
369610
370221
  sessionId,
369611
- _pluginReconnectKey
370222
+ _pluginReconnectKey,
370223
+ _cwdReconnectKey
369612
370224
  ]);
369613
370225
  import_react110.useEffect(() => {
369614
370226
  const timers = reconnectTimersRef.current;
@@ -411884,7 +412496,7 @@ var exports_cd = {};
411884
412496
  __export(exports_cd, {
411885
412497
  call: () => call46
411886
412498
  });
411887
- var USAGE2 = "Usage: /cd [path] (no argument = show current session cwd)", call46 = async (_args, _context) => {
412499
+ var USAGE2 = "Usage: /cd [path] (no argument = show current session cwd)", call46 = async (_args, context) => {
411888
412500
  const arg = (_args ?? "").trim();
411889
412501
  if (arg === "") {
411890
412502
  return {
@@ -411895,6 +412507,10 @@ ${USAGE2}`
411895
412507
  }
411896
412508
  try {
411897
412509
  setCwd2(arg, pwd());
412510
+ context.setAppState((prev) => ({
412511
+ ...prev,
412512
+ mcp: { ...prev.mcp, cwdReconnectKey: prev.mcp.cwdReconnectKey + 1 }
412513
+ }));
411898
412514
  return {
411899
412515
  type: "text",
411900
412516
  value: `Session working directory changed to: ${pwd()}`
@@ -428475,7 +429091,7 @@ function getHttpHookPolicy() {
428475
429091
  allowedEnvVars: settings.httpHookAllowedEnvVars
428476
429092
  };
428477
429093
  }
428478
- function urlMatchesPattern2(url, pattern) {
429094
+ function urlMatchesPattern3(url, pattern) {
428479
429095
  const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
428480
429096
  const regexStr = escaped.replace(/\*/g, ".*");
428481
429097
  return new RegExp(`^${regexStr}$`).test(url);
@@ -428497,7 +429113,7 @@ function interpolateEnvVars(value, allowedEnvVars) {
428497
429113
  async function execHttpHook(hook, _hookEvent, jsonInput, signal) {
428498
429114
  const policy = getHttpHookPolicy();
428499
429115
  if (policy.allowedUrls !== undefined) {
428500
- const matched = policy.allowedUrls.some((p) => urlMatchesPattern2(hook.url, p));
429116
+ const matched = policy.allowedUrls.some((p) => urlMatchesPattern3(hook.url, p));
428501
429117
  if (!matched) {
428502
429118
  const msg = `HTTP hook blocked: ${hook.url} does not match any pattern in allowedHttpHookUrls`;
428503
429119
  logForDebugging3(msg, { level: "warn" });
@@ -431302,6 +431918,30 @@ var init_hooks7 = __esm(() => {
431302
431918
  TOOL_HOOK_EXECUTION_TIMEOUT_MS = 10 * 60 * 1000;
431303
431919
  });
431304
431920
 
431921
+ // src/tui/contextBodies/compactModelSwitch.ts
431922
+ function recordMainLoopModelSwitch(previous, next) {
431923
+ if (!previous || previous === next) {
431924
+ previousMainLoopModel = null;
431925
+ return;
431926
+ }
431927
+ previousMainLoopModel = previous;
431928
+ }
431929
+ function resolveSwitchedCompactModel(current) {
431930
+ const previous = previousMainLoopModel;
431931
+ if (!previous || !current || previous === current)
431932
+ return;
431933
+ const previousWindow = getProviderContextWindow(previous) ?? HARD_DEFAULT_CONTEXT_WINDOW;
431934
+ const currentWindow = getProviderContextWindow(current) ?? HARD_DEFAULT_CONTEXT_WINDOW;
431935
+ return previousWindow > currentWindow ? previous : undefined;
431936
+ }
431937
+ function formatCompactStartMessage(summaryModel) {
431938
+ return summaryModel ? `Compacting conversation (summary: ${summaryModel})` : "Compacting conversation";
431939
+ }
431940
+ var previousMainLoopModel = null;
431941
+ var init_compactModelSwitch = __esm(() => {
431942
+ init_modelprovider2();
431943
+ });
431944
+
431305
431945
  // src/tui/utils/memory/types.ts
431306
431946
  var MEMORY_TYPE_VALUES;
431307
431947
  var init_types17 = __esm(() => {
@@ -432222,7 +432862,11 @@ async function streamCompactSummary({
432222
432862
  }
432223
432863
  const retryEnabled = getFeatureValue_CACHED_MAY_BE_STALE("atlas_compact_streaming_retry", false);
432224
432864
  const maxAttempts = retryEnabled ? MAX_COMPACT_STREAMING_RETRIES : 1;
432225
- const compactModel = modelOverride ?? context.options.mainLoopModel;
432865
+ const compactModel = modelOverride ?? resolveSwitchedCompactModel(context.options.mainLoopModel) ?? context.options.mainLoopModel;
432866
+ context.onCompactProgress?.({
432867
+ type: "compact_start",
432868
+ summaryModel: compactModel
432869
+ });
432226
432870
  for (let attempt = 1;attempt <= maxAttempts; attempt++) {
432227
432871
  let hasStartedStreaming = false;
432228
432872
  let response;
@@ -432475,6 +433119,7 @@ var init_compact4 = __esm(() => {
432475
433119
  init_shared();
432476
433120
  init_uniqBy();
432477
433121
  init_atlas();
433122
+ init_compactModelSwitch();
432478
433123
  init_bootstrapState();
432479
433124
  init_bootstrapState();
432480
433125
  init_FileReadTool();
@@ -433193,6 +433838,7 @@ function wireContextHostPorts() {
433193
433838
  });
433194
433839
  setAutoCompactSettingsSource(() => getGlobalConfig().autoCompactEnabled);
433195
433840
  setAutoCompactWindowSettingsSource(() => getInitialSettings2().autoCompactWindow);
433841
+ setIdleCompactionSettingsSource(() => getInitialSettings2().idleCompaction);
433196
433842
  setLlmTimeoutSettingsSource(() => getInitialSettings2().llmTimeoutMs);
433197
433843
  setEffortByModelSource(() => getEffortByModel());
433198
433844
  setTimeBasedMCConfigSource(() => getFeatureValue_CACHED_MAY_BE_STALE("atlas_slate_heron", TIME_BASED_MC_CONFIG_DEFAULTS));
@@ -435648,6 +436294,9 @@ function onChangeAppState({
435648
436294
  }
435649
436295
  notifyPermissionModeChanged(newMode);
435650
436296
  }
436297
+ if (newState.mainLoopModel !== oldState.mainLoopModel) {
436298
+ recordMainLoopModelSwitch(oldState.mainLoopModel, newState.mainLoopModel);
436299
+ }
435651
436300
  if (newState.mainLoopModel !== oldState.mainLoopModel && newState.mainLoopModel === null) {
435652
436301
  updateSettingsForSource2("userSettings", { model: undefined });
435653
436302
  setMainLoopModelOverride(null);
@@ -435689,6 +436338,7 @@ function onChangeAppState({
435689
436338
  }
435690
436339
  var init_onChangeAppState = __esm(() => {
435691
436340
  init_bootstrapState();
436341
+ init_compactModelSwitch();
435692
436342
  init_auth4();
435693
436343
  init_config6();
435694
436344
  init_errors4();
@@ -470055,6 +470705,32 @@ var init_useMailboxBridge = __esm(() => {
470055
470705
 
470056
470706
  // src/tui/replLoopDeps.ts
470057
470707
  function buildReplLoopParams(m) {
470708
+ let prevPoolSig = (m.tools ?? []).map((t) => t.name).join(",");
470709
+ const refreshRoundContext = (messages) => {
470710
+ const appState = m.toolUseContext?.getAppState?.();
470711
+ const liveMcpTools = appState?.mcp?.tools;
470712
+ if (!liveMcpTools)
470713
+ return null;
470714
+ const pool = assembleToolPool(m.toolPermissionContext, liveMcpTools);
470715
+ const sig = pool.map((t) => t.name).join(",");
470716
+ const tuiMessages = messages;
470717
+ const atts = [
470718
+ ...getDeferredToolsDeltaAttachment(pool, m.mainLoopModel, tuiMessages, {
470719
+ callSite: "round_refresh",
470720
+ querySource: m.querySource
470721
+ }),
470722
+ ...getMcpInstructionsDeltaAttachment(m.toolUseContext.options.mcpClients ?? [], pool, m.mainLoopModel, tuiMessages)
470723
+ ];
470724
+ if (sig === prevPoolSig && atts.length === 0)
470725
+ return null;
470726
+ prevPoolSig = sig;
470727
+ return {
470728
+ tools: pool,
470729
+ ...atts.length > 0 ? {
470730
+ appendedMessages: atts.map((att) => createAttachmentMessage(att))
470731
+ } : {}
470732
+ };
470733
+ };
470058
470734
  return buildAgentLoopParams({
470059
470735
  messages: m.messages,
470060
470736
  userContext: m.userContext,
@@ -470070,11 +470746,14 @@ function buildReplLoopParams(m) {
470070
470746
  toolUseContext: m.toolUseContext,
470071
470747
  querySource: m.querySource,
470072
470748
  unboundedTurns: true,
470073
- maxGoalTurns: m.maxGoalTurns
470749
+ maxGoalTurns: m.maxGoalTurns,
470750
+ refreshRoundContext
470074
470751
  });
470075
470752
  }
470076
470753
  var init_replLoopDeps = __esm(() => {
470077
470754
  init_agentLoopDeps();
470755
+ init_tools3();
470756
+ init_attachments();
470078
470757
  });
470079
470758
 
470080
470759
  // src/tui/hooks/useMergedClients.ts
@@ -479753,7 +480432,7 @@ Error: sandbox required but unavailable: ${reason}
479753
480432
  setSpinnerMessage(event.hookType === "pre_compact" ? "Running PreCompact hooks…" : event.hookType === "post_compact" ? "Running PostCompact hooks…" : "Running SessionStart hooks…");
479754
480433
  break;
479755
480434
  case "compact_start":
479756
- setSpinnerMessage("Compacting conversation");
480435
+ setSpinnerMessage(formatCompactStartMessage(event.summaryModel));
479757
480436
  break;
479758
480437
  case "compact_end":
479759
480438
  setSpinnerMessage(null);
@@ -481809,6 +482488,7 @@ var init_REPL = __esm(() => {
481809
482488
  init_prompts2();
481810
482489
  init_systemPrompt();
481811
482490
  init_context5();
482491
+ init_compactModelSwitch();
481812
482492
  init_memoryFiles();
481813
482493
  init_backgroundHousekeeping();
481814
482494
  init_cost_tracker();
@@ -493280,7 +493960,7 @@ ${formattedErrors}
493280
493960
  const {
493281
493961
  allowed,
493282
493962
  blocked
493283
- } = filterMcpServersByPolicy(scopedConfigs);
493963
+ } = filterMcpServersByPolicy2(scopedConfigs);
493284
493964
  if (blocked.length > 0) {
493285
493965
  process.stderr.write(`Warning: MCP ${plural2(blocked.length, "server")} blocked by enterprise policy: ${blocked.join(", ")}
493286
493966
  `);
@@ -493961,7 +494641,8 @@ ${inputPrompt}` : mergePrompt;
493961
494641
  tools: [],
493962
494642
  commands: [],
493963
494643
  resources: {},
493964
- pluginReconnectKey: 0
494644
+ pluginReconnectKey: 0,
494645
+ cwdReconnectKey: 0
493965
494646
  },
493966
494647
  plugins: {
493967
494648
  enabled: [],