@cnwenf/occ 2.1.328 → 2.1.330

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- globalThis.MACRO={"VERSION":"2.1.328","BINARY_NAME":"occ","BUILD_TIME":"2026-09-10T19:48:17.557Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
2
+ globalThis.MACRO={"VERSION":"2.1.330","BINARY_NAME":"occ","BUILD_TIME":"2026-09-12T00:55:03.697Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
3
3
  // @bun
4
4
  var __create = Object.create;
5
5
  var __getProtoOf = Object.getPrototypeOf;
@@ -59707,6 +59707,22 @@ var init_types2 = __esm(() => {
59707
59707
  prUrlTemplate: exports_external.string().optional().describe('URL template for the footer PR badge (e.g. "https://internal-review.example.com/pr/{number}"). Uses {number} as the PR number placeholder. Defaults to github.com.'),
59708
59708
  alwaysThinkingEnabled: exports_external.boolean().optional().describe("When false, thinking is disabled. When absent or true, thinking is " + "enabled automatically for supported models."),
59709
59709
  effortLevel: exports_external.enum(["low", "medium", "high", "xhigh"]).optional().catch(undefined).describe("Persisted effort level for supported models."),
59710
+ maxEffortLevel: exports_external.enum(["low", "medium", "high", "xhigh", "max"]).optional().catch(undefined).describe("Maximum effort level. Anything above it (an /effort or /model pick, --effort, CLAUDE_CODE_EFFORT_LEVEL, a model default) is clamped to it, on every provider including Bedrock, Vertex and Foundry. Combines with an organization's per-model effort cap by taking the lower of the two; across settings files the lowest value wins, and modelSettings.<model>.maxEffortLevel replaces it per model. Enforced client-side: an effort supplied through CLAUDE_CODE_EXTRA_BODY is not clamped."),
59711
+ modelSettings: exports_external.preprocess((value) => {
59712
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
59713
+ return value;
59714
+ }
59715
+ const stripped = {};
59716
+ for (const [key, entry] of Object.entries(value)) {
59717
+ if (!Object.hasOwn(Object.prototype, key)) {
59718
+ stripped[key] = entry;
59719
+ }
59720
+ }
59721
+ return stripped;
59722
+ }, exports_external.record(exports_external.string(), exports_external.object({
59723
+ effortLevel: exports_external.enum(["low", "medium", "high", "xhigh"]).optional().catch(undefined).describe("Persisted effort level for this model."),
59724
+ maxEffortLevel: exports_external.enum(["low", "medium", "high", "xhigh", "max"]).optional().catch(undefined).describe('Maximum effort level for this model. Within one settings file it replaces the top-level maxEffortLevel for the model ("max" exempts it); across settings files the lowest applicable value wins. Keyed like effortLevel: the canonical model name also matches its dated, [1m], Bedrock and Vertex spellings.')
59725
+ }).passthrough().optional().catch(undefined))).optional().catch(undefined).describe("Per-model settings keyed by canonical model name."),
59710
59726
  dynamicWorkflowSize: exports_external.enum(["small", "medium", "large"]).optional().catch(undefined).describe("Advisory guideline for how large Claude makes dynamic workflows (small/medium/large agent counts). Not an enforced cap."),
59711
59727
  advisorModel: exports_external.string().optional().describe("Advisor model for the server-side advisor tool."),
59712
59728
  fastMode: exports_external.boolean().optional().describe("When true, fast mode is enabled. When absent or false, fast mode is off."),
@@ -203580,12 +203596,15 @@ function isPathInSandboxWriteAllowlist(resolvedPath) {
203580
203596
  }
203581
203597
  function isPathAllowed(resolvedPath, context4, operationType, precomputedPathsToCheck) {
203582
203598
  const permissionType = operationType === "read" ? "read" : "edit";
203583
- const denyRule = matchingRuleForInput(resolvedPath, context4, permissionType, "deny");
203584
- if (denyRule !== null) {
203585
- return {
203586
- allowed: false,
203587
- decisionReason: { type: "rule", rule: denyRule }
203588
- };
203599
+ const pathsToCheck = precomputedPathsToCheck ?? getPathsForPermissionCheck(resolvedPath);
203600
+ for (const pathToCheck of pathsToCheck) {
203601
+ const denyRule = matchingRuleForInput(pathToCheck, context4, permissionType, "deny");
203602
+ if (denyRule !== null) {
203603
+ return {
203604
+ allowed: false,
203605
+ decisionReason: { type: "rule", rule: denyRule }
203606
+ };
203607
+ }
203589
203608
  }
203590
203609
  if (operationType !== "read") {
203591
203610
  const internalEditResult = checkEditableInternalPath(resolvedPath, {});
@@ -203938,6 +203957,122 @@ var init_thinking = __esm(() => {
203938
203957
  ];
203939
203958
  });
203940
203959
 
203960
+ // src/utils/effort/cap.ts
203961
+ function effortLevelIndex(level) {
203962
+ return EFFORT_LEVELS.indexOf(level);
203963
+ }
203964
+ function isKnownEffortLevel(value) {
203965
+ return typeof value === "string" && EFFORT_LEVELS.includes(value);
203966
+ }
203967
+ function getSettingsEffortCap(model) {
203968
+ const sources = getEnabledSettingSources().map((source) => getSettingsForSource(source));
203969
+ const canonicalTarget = sources.some((settings) => Object.values(settings?.modelSettings ?? {}).some((entry) => entry?.maxEffortLevel !== undefined)) ? getCanonicalName(model) : undefined;
203970
+ let lowest = null;
203971
+ for (const settings of sources) {
203972
+ if (!settings)
203973
+ continue;
203974
+ let perFile;
203975
+ if (canonicalTarget !== undefined) {
203976
+ for (const [key, entry] of Object.entries(settings.modelSettings ?? {})) {
203977
+ if (Object.hasOwn(Object.prototype, key))
203978
+ continue;
203979
+ const candidate = entry?.maxEffortLevel;
203980
+ if (candidate !== undefined && (perFile === undefined || effortLevelIndex(candidate) < effortLevelIndex(perFile)) && getCanonicalName(key) === canonicalTarget) {
203981
+ perFile = candidate;
203982
+ }
203983
+ }
203984
+ }
203985
+ perFile ??= settings.maxEffortLevel;
203986
+ if (perFile !== undefined && perFile !== "max" && (lowest === null || effortLevelIndex(perFile) < effortLevelIndex(lowest))) {
203987
+ lowest = perFile;
203988
+ }
203989
+ }
203990
+ return lowest;
203991
+ }
203992
+ function getEffectiveEffortCap(model) {
203993
+ const cap = getSettingsEffortCap(model);
203994
+ return cap === "max" ? null : cap;
203995
+ }
203996
+ function isEffortLevelAllowed(level, model) {
203997
+ const cap = getEffectiveEffortCap(model);
203998
+ return cap === null || effortLevelIndex(level) <= effortLevelIndex(cap);
203999
+ }
204000
+ function getAllowedEffortLevels(model) {
204001
+ return EFFORT_LEVELS.filter((level) => isEffortLevelAllowed(level, model));
204002
+ }
204003
+ function modelSupportsEffortLevel(model, level) {
204004
+ if (level === "xhigh")
204005
+ return modelSupportsXhighEffort(model);
204006
+ if (level === "max")
204007
+ return modelSupportsMaxEffort(model);
204008
+ return true;
204009
+ }
204010
+ function clampEffortToCap(value, model) {
204011
+ const cap = getEffectiveEffortCap(model);
204012
+ if (cap !== null && isKnownEffortLevel(value)) {
204013
+ return effortLevelIndex(value) > effortLevelIndex(cap) ? cap : value;
204014
+ }
204015
+ return value;
204016
+ }
204017
+ function applyEffortCapabilityDowngrade(value, model) {
204018
+ let result = value;
204019
+ if (result === "max" && !modelSupportsMaxEffort(model))
204020
+ result = "high";
204021
+ if (result === "xhigh" && !modelSupportsXhighEffort(model))
204022
+ result = "high";
204023
+ return result;
204024
+ }
204025
+ function clampEffortValue(value, model) {
204026
+ return applyEffortCapabilityDowngrade(clampEffortToCap(value, model), model);
204027
+ }
204028
+ function hasEffortLevelsAboveCap(model) {
204029
+ const cap = getEffectiveEffortCap(model);
204030
+ if (cap === null)
204031
+ return false;
204032
+ return EFFORT_LEVELS.some((level) => effortLevelIndex(level) > effortLevelIndex(cap) && modelSupportsEffortLevel(model, level));
204033
+ }
204034
+ function getEffortCapWarning(requested, model) {
204035
+ if (!isKnownEffortLevel(requested))
204036
+ return null;
204037
+ const cap = getEffectiveEffortCap(model);
204038
+ if (cap === null || effortLevelIndex(requested) <= effortLevelIndex(cap)) {
204039
+ return null;
204040
+ }
204041
+ const using = clampEffortValue(requested, model);
204042
+ return `Effort '${requested}' exceeds the cap for ${model} set by your settings or organization; using '${using}'.`;
204043
+ }
204044
+ function emitStartupEffortCapWarning(requestedEffort, model, outputFormat) {
204045
+ const warning = getEffortCapWarning(requestedEffort, model);
204046
+ if (warning === null)
204047
+ return;
204048
+ if (outputFormat !== "json" && outputFormat !== "stream-json" && process.env.CLAUDE_CODE_SESSION_KIND !== "bg") {
204049
+ console.warn(source_default.yellow(warning));
204050
+ return;
204051
+ }
204052
+ logForDebugging(`[effort] ${warning}`);
204053
+ }
204054
+ function isUltracodeAvailableForModel(model) {
204055
+ return model === undefined || modelSupportsXhighEffort(model) && isEffortLevelAllowed("xhigh", model);
204056
+ }
204057
+ function formatEffortValidOptions(model) {
204058
+ const levels = getAllowedEffortLevels(model);
204059
+ const ultracode = isUltracodeAvailableForModel(model) ? ", ultracode" : "";
204060
+ return `${levels.join(", ")}${ultracode}, auto`;
204061
+ }
204062
+ function buildEffortArgumentHint(open6, close, model) {
204063
+ const levels = getAllowedEffortLevels(model);
204064
+ const ultracode = isUltracodeAvailableForModel(model) ? "|ultracode" : "";
204065
+ return `${open6}${levels.join("|")}${ultracode}|auto${close}`;
204066
+ }
204067
+ var init_cap = __esm(() => {
204068
+ init_source();
204069
+ init_debug();
204070
+ init_model();
204071
+ init_constants2();
204072
+ init_settings2();
204073
+ init_effort();
204074
+ });
204075
+
203941
204076
  // src/utils/effort.ts
203942
204077
  function modelSupportsEffort(model) {
203943
204078
  const m5 = model.toLowerCase();
@@ -204026,24 +204161,30 @@ function getEffortEnvOverride() {
204026
204161
  }
204027
204162
  function resolveAppliedEffort(model, appStateEffortValue) {
204028
204163
  const envOverride = getEffortEnvOverride();
204029
- if (envOverride === null) {
204164
+ const hasSettingsCap = getSettingsEffortCap(model) !== null;
204165
+ if (envOverride === null && !hasSettingsCap) {
204030
204166
  return;
204031
204167
  }
204032
- const resolved = envOverride ?? appStateEffortValue ?? getDefaultEffortForModel(model);
204033
- if (resolved === "max" && !modelSupportsMaxEffort(model)) {
204034
- return "high";
204168
+ const modelDefault = getDefaultEffortForModel(model);
204169
+ let resolved = envOverride ?? (envOverride === null ? modelDefault : undefined) ?? appStateEffortValue ?? modelDefault;
204170
+ if (typeof resolved === "number" && hasSettingsCap) {
204171
+ resolved = "high";
204035
204172
  }
204036
- if (resolved === "xhigh" && !modelSupportsXhighEffort(model)) {
204037
- return "high";
204173
+ if (resolved === undefined) {
204174
+ return;
204038
204175
  }
204039
- return resolved;
204176
+ return clampEffortValue(resolved, model);
204040
204177
  }
204041
204178
  function resolveConfiguredEffort(model, appStateEffortValue) {
204042
204179
  const envOverride = getEffortEnvOverride();
204043
204180
  if (envOverride === null) {
204044
204181
  return;
204045
204182
  }
204046
- return envOverride ?? appStateEffortValue ?? getDefaultEffortForModel(model);
204183
+ const resolved = envOverride ?? appStateEffortValue ?? getDefaultEffortForModel(model);
204184
+ if (resolved === undefined) {
204185
+ return;
204186
+ }
204187
+ return clampEffortToCap(resolved, model);
204047
204188
  }
204048
204189
  function getDisplayedEffortLevel(model, appStateEffort) {
204049
204190
  const configured = resolveConfiguredEffort(model, appStateEffort) ?? "high";
@@ -204148,6 +204289,7 @@ var init_effort = __esm(() => {
204148
204289
  init_providers();
204149
204290
  init_modelSupportOverrides();
204150
204291
  init_envUtils();
204292
+ init_cap();
204151
204293
  EFFORT_LEVELS = [
204152
204294
  "low",
204153
204295
  "medium",
@@ -377344,43 +377486,40 @@ function getMaxBashTimeoutMs(env6 = process.env) {
377344
377486
  var DEFAULT_TIMEOUT_MS = 120000, MAX_TIMEOUT_MS = 600000;
377345
377487
 
377346
377488
  // src/utils/todoToolsAvailability.ts
377347
- function isModelAtOrAboveRestrictedThreshold(modelId, restricted) {
377348
- const match = /^claude-([a-z]+)-(\d+(?:-\d+)*)$/.exec(modelId);
377349
- const family = match?.[1];
377350
- const version5 = match?.[2];
377351
- if (!family || !version5) {
377352
- return false;
377353
- }
377354
- const threshold = restricted.find(([f4]) => f4 === family)?.[1];
377355
- if (!threshold) {
377356
- return false;
377357
- }
377358
- const segments = version5.split("-").map(Number);
377359
- for (let i6 = 0;i6 < Math.max(segments.length, threshold.length); i6++) {
377360
- const diff2 = (segments[i6] ?? 0) - (threshold[i6] ?? 0);
377361
- if (diff2 !== 0) {
377362
- return diff2 > 0;
377363
- }
377364
- }
377365
- return true;
377366
- }
377367
377489
  function areTodoToolsAvailable() {
377368
377490
  const model = getMainLoopModel();
377369
- if (!isModelAtOrAboveRestrictedThreshold(model, TODO_TOOL_RESTRICTED_MODELS)) {
377491
+ if (model === undefined) {
377492
+ return true;
377493
+ }
377494
+ if (model.includes("application-inference-profile")) {
377495
+ return true;
377496
+ }
377497
+ if (TODO_TOOL_ALLOWED_MODELS.has(model)) {
377370
377498
  return true;
377371
377499
  }
377372
377500
  return isEnvTruthy(process.env.CLAUDE_CODE_ENABLE_TODO_TOOLS);
377373
377501
  }
377374
- var TODO_TOOL_RESTRICTED_MODELS;
377502
+ var TODO_TOOL_ALLOWED_MODELS;
377375
377503
  var init_todoToolsAvailability = __esm(() => {
377376
377504
  init_envUtils();
377377
377505
  init_model();
377378
- TODO_TOOL_RESTRICTED_MODELS = [
377379
- ["opus", [4, 8]],
377380
- ["sonnet", [5]],
377381
- ["fable", [5]],
377382
- ["mythos", [5]]
377383
- ];
377506
+ TODO_TOOL_ALLOWED_MODELS = new Set([
377507
+ "claude-3-opus",
377508
+ "claude-3-sonnet",
377509
+ "claude-3-haiku",
377510
+ "claude-3-5-sonnet",
377511
+ "claude-3-5-haiku",
377512
+ "claude-3-7-sonnet",
377513
+ "claude-opus-4-0",
377514
+ "claude-opus-4-1",
377515
+ "claude-opus-4-5",
377516
+ "claude-opus-4-6",
377517
+ "claude-opus-4-7",
377518
+ "claude-sonnet-4-0",
377519
+ "claude-sonnet-4-5",
377520
+ "claude-sonnet-4-6",
377521
+ "claude-haiku-4-5"
377522
+ ]);
377384
377523
  });
377385
377524
 
377386
377525
  // src/utils/todo/types.ts
@@ -387587,6 +387726,518 @@ var init_common4 = __esm(() => {
387587
387726
  trackedTabIds = new Set;
387588
387727
  });
387589
387728
 
387729
+ // src/services/mcp/redaction.ts
387730
+ function splitEnvVarSegments(template) {
387731
+ const segments = [];
387732
+ let cursor = 0;
387733
+ for (const match of template.matchAll(new RegExp(ENV_VAR_PATTERN, "g"))) {
387734
+ segments.push(template.slice(cursor, match.index));
387735
+ cursor = match.index + match[0].length;
387736
+ }
387737
+ segments.push(template.slice(cursor));
387738
+ return segments;
387739
+ }
387740
+ function redactEnvVarPlaceholders(value) {
387741
+ return value.replace(new RegExp(ENV_VAR_PATTERN, "g"), (match) => "x".repeat(match.length));
387742
+ }
387743
+ function normalizeEnvVarRefs(value) {
387744
+ return value.replace(new RegExp(ENV_VAR_PATTERN, "g"), (_match, name3) => `\${${name3}}`);
387745
+ }
387746
+ function escapeRegExp2(value) {
387747
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
387748
+ }
387749
+ function recoverExpandedSecrets(template, expanded) {
387750
+ if (!template || !expanded || !template.includes("${"))
387751
+ return [];
387752
+ const segments = splitEnvVarSegments(template);
387753
+ if (segments.length < 2)
387754
+ return [];
387755
+ if (expanded.length > MAX_RECOVER_EXPANDED_LENGTH || segments.length > MAX_RECOVER_SEGMENTS)
387756
+ return [];
387757
+ const escapedSegments = segments.map(escapeRegExp2);
387758
+ const secrets = [];
387759
+ if (segments.length === 2) {
387760
+ const [prefix = "", suffix = ""] = segments;
387761
+ if (expanded.length >= prefix.length + suffix.length && expanded.startsWith(prefix) && expanded.endsWith(suffix))
387762
+ secrets.push(expanded.slice(prefix.length, expanded.length - suffix.length));
387763
+ } else if (segments.length === 3) {
387764
+ const [prefix = "", middle = "", suffix = ""] = segments;
387765
+ if (expanded.startsWith(prefix) && expanded.endsWith(suffix)) {
387766
+ const inner = expanded.slice(prefix.length, expanded.length - suffix.length);
387767
+ if (middle === "")
387768
+ secrets.push(inner);
387769
+ else {
387770
+ const positions = [];
387771
+ for (let idx = inner.indexOf(middle);idx !== -1 && positions.length <= MAX_MIDDLE_OCCURRENCES; idx = inner.indexOf(middle, idx + 1))
387772
+ positions.push(idx);
387773
+ const chosen = positions.length > MAX_MIDDLE_OCCURRENCES ? [positions[0] ?? 0, inner.lastIndexOf(middle)] : positions;
387774
+ for (const position2 of chosen)
387775
+ secrets.push(inner.slice(0, position2), inner.slice(position2 + middle.length));
387776
+ }
387777
+ }
387778
+ } else {
387779
+ for (let i6 = 1;i6 < segments.length - 1; i6++)
387780
+ if (segments[i6] === "")
387781
+ return [];
387782
+ let pattern = "^";
387783
+ for (let i6 = 0;i6 < escapedSegments.length; i6++) {
387784
+ pattern += escapedSegments[i6];
387785
+ if (i6 < escapedSegments.length - 1) {
387786
+ const next = segments[i6 + 1] ?? "";
387787
+ if (next === "")
387788
+ pattern += "([\\s\\S]*)";
387789
+ else {
387790
+ const firstChar = next.charAt(0).replace(/[.*+?^${}()|[\]-]/g, "\\$&");
387791
+ pattern += `([^${firstChar}]*)`;
387792
+ }
387793
+ }
387794
+ }
387795
+ const match = expanded.match(new RegExp(`${pattern}$`));
387796
+ if (match)
387797
+ secrets.push(...match.slice(1).filter((secret) => secret !== ""));
387798
+ }
387799
+ return [...new Set(secrets)];
387800
+ }
387801
+ function collectConfigSecrets(authored, resolved) {
387802
+ if (!authored)
387803
+ return [];
387804
+ const secrets = [];
387805
+ const collect = (template, expanded) => {
387806
+ if (typeof template === "string" && typeof expanded === "string")
387807
+ secrets.push(...recoverExpandedSecrets(template, expanded));
387808
+ };
387809
+ if ("url" in authored && "url" in resolved)
387810
+ collect(authored.url, resolved.url);
387811
+ if ("command" in authored && "command" in resolved) {
387812
+ collect(authored.command, resolved.command);
387813
+ const authoredArgs = Array.isArray(authored.args) ? authored.args : [];
387814
+ const resolvedArgs = Array.isArray(resolved.args) ? resolved.args : [];
387815
+ for (let i6 = 0;i6 < Math.min(authoredArgs.length, resolvedArgs.length); i6++)
387816
+ collect(authoredArgs[i6], resolvedArgs[i6]);
387817
+ }
387818
+ for (const field of ["headers", "env"]) {
387819
+ const authoredRecord = field in authored ? authored[field] : undefined;
387820
+ const resolvedRecord = field in resolved ? resolved[field] : undefined;
387821
+ if (authoredRecord && resolvedRecord && typeof authoredRecord === "object" && typeof resolvedRecord === "object")
387822
+ for (const [key2, value] of Object.entries(authoredRecord))
387823
+ collect(value, resolvedRecord[key2]);
387824
+ }
387825
+ return secrets;
387826
+ }
387827
+ function matchesEnvVarTemplate(template, expanded) {
387828
+ const segments = splitEnvVarSegments(template);
387829
+ if (segments.length === 1)
387830
+ return template === expanded;
387831
+ const prefix = segments[0] ?? "";
387832
+ const suffix = segments.at(-1) ?? "";
387833
+ if (!expanded.startsWith(prefix) || !expanded.endsWith(suffix))
387834
+ return false;
387835
+ let cursor = prefix.length;
387836
+ const limit = expanded.length - suffix.length;
387837
+ for (let i6 = 1;i6 < segments.length - 1; i6++) {
387838
+ const segment2 = segments[i6] ?? "";
387839
+ const idx = expanded.indexOf(segment2, cursor);
387840
+ if (idx === -1 || idx + segment2.length > limit)
387841
+ return false;
387842
+ cursor = idx + segment2.length;
387843
+ }
387844
+ return cursor <= limit;
387845
+ }
387846
+ function recordField(config6, field) {
387847
+ const value = config6[field];
387848
+ return value && typeof value === "object" ? value : undefined;
387849
+ }
387850
+ function recordFieldsMatch(authored, expanded) {
387851
+ const authoredEntries = Object.entries(authored ?? {});
387852
+ const expandedRecord = expanded ?? {};
387853
+ if (authoredEntries.length !== Object.keys(expandedRecord).length)
387854
+ return false;
387855
+ return authoredEntries.every(([key2, value]) => typeof expandedRecord[key2] === "string" && matchesEnvVarTemplate(value, expandedRecord[key2]));
387856
+ }
387857
+ function isWebUrl(url3) {
387858
+ if (!URL.canParse(url3))
387859
+ return false;
387860
+ const { protocol } = new URL(url3);
387861
+ return protocol === "http:" || protocol === "https:" || protocol === "ws:" || protocol === "wss:";
387862
+ }
387863
+ function getServerUrl(config6) {
387864
+ return "url" in config6 ? config6.url : null;
387865
+ }
387866
+ function getStdioCommandParts(config6) {
387867
+ if (config6.type !== undefined && config6.type !== "stdio")
387868
+ return null;
387869
+ if (!("command" in config6))
387870
+ return null;
387871
+ return [config6.command, ...config6.args ?? []];
387872
+ }
387873
+ function getServerTypeLabel(config6) {
387874
+ return config6.type ?? ("command" in config6 ? "stdio" : "unknown");
387875
+ }
387876
+ function splitUrlParts(url3, maskedUrl = url3) {
387877
+ const findSplit = (from) => {
387878
+ let end2 = url3.length;
387879
+ for (const delimiter2 of ["/", "?", "#", "\\"]) {
387880
+ const idx = maskedUrl.indexOf(delimiter2, from);
387881
+ if (idx !== -1 && idx < end2)
387882
+ end2 = idx;
387883
+ }
387884
+ return end2;
387885
+ };
387886
+ const schemeSeparator = maskedUrl.indexOf("://");
387887
+ const start = schemeSeparator !== -1 && schemeSeparator < findSplit(0) && /^[A-Za-z][A-Za-z0-9+.-]*$/.test(maskedUrl.slice(0, schemeSeparator)) ? schemeSeparator + 3 : 0;
387888
+ const end = findSplit(start);
387889
+ return {
387890
+ scheme: url3.slice(0, start),
387891
+ authority: url3.slice(start, end),
387892
+ rest: url3.slice(end)
387893
+ };
387894
+ }
387895
+ function authorityHasEnvVarRef(url3) {
387896
+ return splitUrlParts(url3, redactEnvVarPlaceholders(url3)).authority.includes("${");
387897
+ }
387898
+ function authoredMatchesExpanded(authored, expanded) {
387899
+ if ((authored.type ?? "stdio") !== (expanded.type ?? "stdio"))
387900
+ return false;
387901
+ const authoredUrl = getServerUrl(authored);
387902
+ const expandedUrl = getServerUrl(expanded);
387903
+ if (authoredUrl !== null || expandedUrl !== null) {
387904
+ const urlsMatchTemplate = (a5, r4) => {
387905
+ const masked = redactEnvVarPlaceholders(a5);
387906
+ const authoredParts = splitUrlParts(a5, masked);
387907
+ const expandedParts = splitUrlParts(r4);
387908
+ const isAllPlaceholder = (value) => splitEnvVarSegments(value).every((segment2) => segment2 === "");
387909
+ if (isAllPlaceholder(a5))
387910
+ return true;
387911
+ if (authoredParts.scheme === "" && isAllPlaceholder(authoredParts.authority))
387912
+ return matchesEnvVarTemplate(a5, r4);
387913
+ const maskedAt = splitUrlParts(masked).authority.lastIndexOf("@");
387914
+ const expandedAt = expandedParts.authority.lastIndexOf("@");
387915
+ if (maskedAt === -1 !== (expandedAt === -1))
387916
+ return false;
387917
+ if (authoredParts.scheme === "")
387918
+ return expandedParts.scheme === "" && !isWebUrl(r4) && matchesEnvVarTemplate(a5, r4);
387919
+ if (expandedParts.scheme === "")
387920
+ return false;
387921
+ return matchesEnvVarTemplate(authoredParts.scheme.toLowerCase(), expandedParts.scheme.toLowerCase()) && (maskedAt === -1 || matchesEnvVarTemplate(authoredParts.authority.slice(0, maskedAt), expandedParts.authority.slice(0, expandedAt))) && matchesEnvVarTemplate(authoredParts.authority.slice(maskedAt + 1), expandedParts.authority.slice(expandedAt + 1)) && matchesEnvVarTemplate(authoredParts.rest, expandedParts.rest);
387922
+ };
387923
+ if (authoredUrl === null || expandedUrl === null)
387924
+ return false;
387925
+ if (!urlsMatchTemplate(authoredUrl, expandedUrl))
387926
+ return false;
387927
+ }
387928
+ const authoredCommand = getStdioCommandParts(authored);
387929
+ const expandedCommand = getStdioCommandParts(expanded);
387930
+ if (authoredCommand !== null || expandedCommand !== null) {
387931
+ if (authoredCommand === null || expandedCommand === null || authoredCommand.length !== expandedCommand.length || !authoredCommand.every((part, i6) => matchesEnvVarTemplate(part, expandedCommand[i6] ?? "")))
387932
+ return false;
387933
+ }
387934
+ return recordFieldsMatch(recordField(authored, "headers"), recordField(expanded, "headers")) && recordFieldsMatch(recordField(authored, "env"), recordField(expanded, "env"));
387935
+ }
387936
+ function getUrlOrigin(url3) {
387937
+ try {
387938
+ const origin2 = new URL(url3).origin;
387939
+ return origin2 === "null" ? undefined : origin2;
387940
+ } catch {
387941
+ return;
387942
+ }
387943
+ }
387944
+ function maskUrlUserinfo(url3) {
387945
+ const masked = redactEnvVarPlaceholders(url3);
387946
+ const { scheme, authority } = splitUrlParts(masked);
387947
+ const schemeLength = scheme.length;
387948
+ const authorityEnd = schemeLength + authority.length;
387949
+ if (masked.includes("@", authorityEnd))
387950
+ return `${normalizeEnvVarRefs(url3.slice(0, schemeLength))}[unparseable-authority]`;
387951
+ const at = authority.lastIndexOf("@");
387952
+ const userinfo = url3.slice(at === -1 ? schemeLength : schemeLength + at + 1, authorityEnd);
387953
+ if (userinfo === "")
387954
+ return;
387955
+ return normalizeEnvVarRefs(url3.slice(0, schemeLength) + userinfo);
387956
+ }
387957
+ function getEndpointForDisplay(params) {
387958
+ const { authoredUnexpanded: authored, expanded } = params;
387959
+ const detail = params.detail ?? "endpoint";
387960
+ if (authored) {
387961
+ const url3 = getServerUrl(authored);
387962
+ if (url3) {
387963
+ if (detail === "endpoint")
387964
+ return normalizeEnvVarRefs(url3);
387965
+ if (authorityHasEnvVarRef(url3))
387966
+ return maskUrlUserinfo(url3);
387967
+ return getUrlOrigin(url3) ?? maskUrlUserinfo(url3);
387968
+ }
387969
+ const commandParts = getStdioCommandParts(authored);
387970
+ if (commandParts)
387971
+ return detail === "endpoint" ? normalizeEnvVarRefs(commandParts.join(" ")) : undefined;
387972
+ return detail === "endpoint" ? getServerTypeLabel(authored) : undefined;
387973
+ }
387974
+ const expandedUrl = getServerUrl(expanded);
387975
+ if (expandedUrl) {
387976
+ const origin2 = getUrlOrigin(expandedUrl);
387977
+ if (origin2 !== undefined)
387978
+ return origin2;
387979
+ }
387980
+ return detail === "endpoint" ? getServerTypeLabel(expanded) : undefined;
387981
+ }
387982
+ function deepNormalizeEnvVarRefs(value) {
387983
+ const walk = (current) => typeof current === "string" ? normalizeEnvVarRefs(current) : Array.isArray(current) ? current.map(walk) : current && typeof current === "object" ? Object.fromEntries(Object.entries(current).map(([key2, child]) => [key2, walk(child)])) : current;
387984
+ return walk(value);
387985
+ }
387986
+ function sanitizeConfigForDisplay(config6) {
387987
+ const typeLabel = getServerTypeLabel(config6);
387988
+ if ("url" in config6) {
387989
+ return {
387990
+ ...config6,
387991
+ url: typeLabel,
387992
+ ..."headers" in config6 && config6.headers && {
387993
+ headers: Object.fromEntries(Object.keys(config6.headers).map((key2) => [key2, "[REDACTED]"]))
387994
+ }
387995
+ };
387996
+ }
387997
+ if ("command" in config6) {
387998
+ return {
387999
+ ...config6,
388000
+ command: typeLabel,
388001
+ ..."args" in config6 && config6.args && { args: [] },
388002
+ ..."env" in config6 && config6.env && {
388003
+ env: Object.fromEntries(Object.keys(config6.env).map((key2) => [key2, "[REDACTED]"]))
388004
+ }
388005
+ };
388006
+ }
388007
+ return config6;
388008
+ }
388009
+ function getKnownScope(config6) {
388010
+ if (!("scope" in config6))
388011
+ return;
388012
+ const scope = config6.scope;
388013
+ return ConfigScopeSchema().options.find((known) => known === scope);
388014
+ }
388015
+ function getDisplayServers(servers, resolveUnexpanded) {
388016
+ const resolverCache = new Map;
388017
+ const display = {};
388018
+ for (const [name3, config6] of Object.entries(servers)) {
388019
+ const scope = getKnownScope(config6);
388020
+ if (scope === undefined) {
388021
+ display[name3] = config6;
388022
+ continue;
388023
+ }
388024
+ if (scope === "claudeai") {
388025
+ display[name3] = deepNormalizeEnvVarRefs(config6);
388026
+ continue;
388027
+ }
388028
+ if (!resolverCache.has(scope))
388029
+ resolverCache.set(scope, resolveUnexpanded(scope));
388030
+ const authored = resolverCache.get(scope)?.[name3];
388031
+ display[name3] = authored && authoredMatchesExpanded(authored, config6) ? deepNormalizeEnvVarRefs(authored) : sanitizeConfigForDisplay(config6);
388032
+ }
388033
+ return display;
388034
+ }
388035
+ function getDisplayConfig(name3, config6, resolveUnexpanded) {
388036
+ return getDisplayServers({ [name3]: config6 }, resolveUnexpanded)[name3] ?? sanitizeConfigForDisplay(config6);
388037
+ }
388038
+ function registerAuthoredUnexpandedConfig(name3, config6) {
388039
+ authoredUnexpandedRegistry.set(name3, config6);
388040
+ }
388041
+ function getAuthoredUnexpandedRegistry() {
388042
+ return authoredUnexpandedRegistry;
388043
+ }
388044
+ function getAuthoredUnexpanded(name3, config6, resolveUnexpanded) {
388045
+ const scope = getKnownScope(config6);
388046
+ if (scope === undefined)
388047
+ return;
388048
+ try {
388049
+ const authored = resolveUnexpanded(scope)?.[name3];
388050
+ return authored && authoredMatchesExpanded(authored, config6) ? authored : undefined;
388051
+ } catch {
388052
+ return;
388053
+ }
388054
+ }
388055
+ function getMcpErrorEndpoint(name3, config6, options, resolveUnexpanded) {
388056
+ const authored = getAuthoredUnexpanded(name3, config6, resolveUnexpanded);
388057
+ if (authored === undefined && getKnownScope(config6) !== undefined)
388058
+ return options?.detail === "origin" ? undefined : getServerTypeLabel(config6);
388059
+ return getEndpointForDisplay({
388060
+ authoredUnexpanded: authored,
388061
+ expanded: config6,
388062
+ cliOwned: false,
388063
+ detail: options?.detail
388064
+ });
388065
+ }
388066
+ function isLabelLikeSecret(candidate) {
388067
+ const parts = candidate.split(/[:=\uFF1A\uFF1D]+/).map((part) => part.trim());
388068
+ let matched = 0;
388069
+ for (const [index2, part] of parts.entries()) {
388070
+ if (part === "")
388071
+ continue;
388072
+ const isNonFinalOrFlag = index2 < parts.length - 1 || part.startsWith("-");
388073
+ if (!LABEL_EXACT_PATTERN.test(part) && !(isNonFinalOrFlag && LABEL_SUFFIX_PATTERN.test(part)))
388074
+ return false;
388075
+ matched++;
388076
+ }
388077
+ return matched > 0;
388078
+ }
388079
+ function redactMcpErrorText(errorText, expanded, endpoint3, authored) {
388080
+ const endpointDisplay = endpoint3 ?? MCP_ENDPOINT_PLACEHOLDER;
388081
+ const registrations = [];
388082
+ const registerSecret = (secret, replacement, options) => {
388083
+ if (secret === undefined)
388084
+ return;
388085
+ if (secret.length < 4)
388086
+ return;
388087
+ if (replacement !== "[redacted]" && replacement.includes(secret))
388088
+ return;
388089
+ registrations.push([secret, replacement, options?.wordBoundary === true]);
388090
+ };
388091
+ const registerRedacted = (secret, replacement = endpointDisplay) => {
388092
+ if (secret === undefined)
388093
+ return;
388094
+ if (replacement.includes(secret) || isLabelLikeSecret(secret.trim()))
388095
+ return;
388096
+ registerSecret(secret, "[redacted]");
388097
+ };
388098
+ const registerWithVariants = (secret, replacement = endpointDisplay) => {
388099
+ if (!secret)
388100
+ return;
388101
+ registerRedacted(secret, replacement);
388102
+ if (secret.includes("+"))
388103
+ registerRedacted(secret.replaceAll("+", " "), replacement);
388104
+ if (secret.includes(" "))
388105
+ registerRedacted(secret.replaceAll(" ", "+"), replacement);
388106
+ for (const variant of [secret, secret.replaceAll("+", " ")]) {
388107
+ const words = variant.split(/\s+/);
388108
+ if (words.length > 1)
388109
+ for (const word of words)
388110
+ registerRedacted(word, replacement);
388111
+ }
388112
+ };
388113
+ const registerUrl = (url3, replacement) => {
388114
+ if (url3 === undefined)
388115
+ return;
388116
+ registerSecret(url3, replacement);
388117
+ try {
388118
+ const parsed = new URL(url3);
388119
+ registerSecret(parsed.href, replacement);
388120
+ if (parsed.origin !== "null")
388121
+ registerSecret(parsed.origin, replacement);
388122
+ registerSecret(parsed.host, replacement);
388123
+ registerSecret(parsed.hostname, replacement);
388124
+ const bareHostname = parsed.hostname.replace(/^\[|\]$/g, "");
388125
+ if (bareHostname !== parsed.hostname)
388126
+ registerSecret(bareHostname, replacement);
388127
+ registerWithVariants(parsed.username, replacement);
388128
+ registerWithVariants(parsed.password, replacement);
388129
+ registerRedacted(parsed.pathname !== "/" ? parsed.pathname : undefined, replacement);
388130
+ for (const segment2 of parsed.pathname.split("/"))
388131
+ registerWithVariants(segment2, replacement);
388132
+ registerRedacted(parsed.search, replacement);
388133
+ for (const [key2, value] of parsed.searchParams.entries()) {
388134
+ registerWithVariants(key2, replacement);
388135
+ registerWithVariants(value, replacement);
388136
+ }
388137
+ for (const pair of parsed.search.replace(/^\?/, "").split("&")) {
388138
+ const eq2 = pair.indexOf("=");
388139
+ if (eq2 === -1)
388140
+ registerWithVariants(pair, replacement);
388141
+ else {
388142
+ registerWithVariants(pair.slice(0, eq2), replacement);
388143
+ registerWithVariants(pair.slice(eq2 + 1), replacement);
388144
+ }
388145
+ }
388146
+ } catch {}
388147
+ };
388148
+ for (const secret of collectConfigSecrets(authored, expanded))
388149
+ registerWithVariants(secret);
388150
+ if ("url" in expanded && typeof expanded.url === "string")
388151
+ registerUrl(expanded.url, endpointDisplay);
388152
+ if ("oauth" in expanded && typeof expanded.oauth?.authServerMetadataUrl === "string") {
388153
+ const metadataUrl = expanded.oauth.authServerMetadataUrl;
388154
+ let replacement = "[redacted]";
388155
+ try {
388156
+ const origin2 = new URL(metadataUrl).origin;
388157
+ if (origin2 !== "null")
388158
+ replacement = origin2;
388159
+ } catch {}
388160
+ registerUrl(metadataUrl, replacement);
388161
+ }
388162
+ if ("command" in expanded && typeof expanded.command === "string") {
388163
+ const authoredCommand = authored && "command" in authored && typeof authored.command === "string" ? normalizeEnvVarRefs(authored.command) : undefined;
388164
+ registerSecret(expanded.command, authoredCommand ?? endpointDisplay, {
388165
+ wordBoundary: true
388166
+ });
388167
+ if (Array.isArray(expanded.args))
388168
+ for (const arg of expanded.args)
388169
+ registerWithVariants(arg);
388170
+ }
388171
+ if ("headers" in expanded && expanded.headers)
388172
+ for (const value of Object.values(expanded.headers))
388173
+ registerWithVariants(value);
388174
+ if ("env" in expanded && expanded.env)
388175
+ for (const value of Object.values(expanded.env))
388176
+ registerWithVariants(value);
388177
+ if ("authToken" in expanded && typeof expanded.authToken === "string")
388178
+ registerWithVariants(expanded.authToken);
388179
+ if (registrations.length === 0)
388180
+ return errorText;
388181
+ registrations.sort((a5, b5) => b5[0].length - a5[0].length);
388182
+ const deduped = new Map;
388183
+ for (const [secret, replacement, wordBoundary] of registrations) {
388184
+ const existing = deduped.get(secret);
388185
+ if (!existing)
388186
+ deduped.set(secret, { replacement, wordBoundary });
388187
+ else if (existing.replacement === "[redacted]" && replacement !== "[redacted]")
388188
+ deduped.set(secret, {
388189
+ replacement,
388190
+ wordBoundary: existing.wordBoundary && wordBoundary
388191
+ });
388192
+ }
388193
+ const spans = [];
388194
+ for (const [secret, entry] of deduped) {
388195
+ const escaped = escapeRegExp2(secret);
388196
+ const pattern = entry.wordBoundary && /^[\w-]+$/.test(secret) ? `(?<![\\w:.-])${escaped}(?![\\w:.-])` : escaped;
388197
+ const regex2 = new RegExp(pattern, "gi");
388198
+ for (let match = regex2.exec(errorText);match !== null; match = regex2.exec(errorText)) {
388199
+ spans.push({
388200
+ start: match.index,
388201
+ end: match.index + match[0].length,
388202
+ replacement: entry.replacement
388203
+ });
388204
+ regex2.lastIndex = match.index + 1;
388205
+ }
388206
+ }
388207
+ spans.sort((a5, b5) => a5.start - b5.start || b5.end - a5.end);
388208
+ const merged = [];
388209
+ for (const span of spans) {
388210
+ const last2 = merged.at(-1);
388211
+ if (last2 && span.start < last2.end)
388212
+ last2.end = Math.max(last2.end, span.end);
388213
+ else
388214
+ merged.push({ ...span });
388215
+ }
388216
+ let result = "";
388217
+ let cursor = 0;
388218
+ for (const span of merged) {
388219
+ result += errorText.slice(cursor, span.start) + span.replacement;
388220
+ cursor = span.end;
388221
+ }
388222
+ result += errorText.slice(cursor);
388223
+ return result;
388224
+ }
388225
+ function redactMcpErrorDetail(name3, config6, errorText, resolveUnexpanded) {
388226
+ try {
388227
+ return redactMcpErrorText(errorText, config6, getMcpErrorEndpoint(name3, config6, { detail: "origin" }, resolveUnexpanded) ?? getServerTypeLabel(config6), getAuthoredUnexpanded(name3, config6, resolveUnexpanded));
388228
+ } catch {
388229
+ return MCP_ERROR_REDACTION_FAILED;
388230
+ }
388231
+ }
388232
+ var MCP_ENDPOINT_PLACEHOLDER = "[mcp-endpoint]", MCP_ERROR_REDACTION_FAILED = "[mcp error detail unavailable: redaction failed]", MAX_RECOVER_EXPANDED_LENGTH = 2000, MAX_RECOVER_SEGMENTS = 9, MAX_MIDDLE_OCCURRENCES = 64, ENV_VAR_PATTERN, authoredUnexpandedRegistry, LABEL_EXACT_PATTERN, LABEL_SUFFIX_PATTERN;
388233
+ var init_redaction = __esm(() => {
388234
+ init_types();
388235
+ ENV_VAR_PATTERN = String.raw`\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-[^}]*)?\}`;
388236
+ authoredUnexpandedRegistry = new Map;
388237
+ LABEL_EXACT_PATTERN = /^(?:bearer|basic|(?:access|refresh|id|client|api|x[-_]api|session|auth)?[-_ ]?(?:token|key|secret|password|authorization|credential)s?)$/i;
388238
+ LABEL_SUFFIX_PATTERN = /(?:^|[^A-Za-z0-9_\s])(?:bearer|basic|token|key|secret|password|authorization|credential)s?$/i;
388239
+ });
388240
+
387590
388241
  // src/utils/plugins/mcpPluginIntegration.ts
387591
388242
  import { join as join78 } from "path";
387592
388243
  async function loadMcpServersFromMcpb(plugin, mcpbPath, errors8) {
@@ -387770,6 +388421,20 @@ function buildMcpUserConfig(plugin, serverName) {
387770
388421
  return;
387771
388422
  return { ...topLevel, ...channelSpecific };
387772
388423
  }
388424
+ function buildAuthoredPluginConfig(config6, plugin) {
388425
+ if (config6.type === undefined || config6.type === "stdio") {
388426
+ return {
388427
+ ...config6,
388428
+ env: {
388429
+ CLAUDE_PLUGIN_ROOT: plugin.path,
388430
+ CLAUDE_PLUGIN_DATA: getPluginDataDir(plugin.source),
388431
+ ...config6.env || {}
388432
+ },
388433
+ scope: "dynamic"
388434
+ };
388435
+ }
388436
+ return { ...config6, scope: "dynamic" };
388437
+ }
387773
388438
  function resolvePluginMcpEnvironment(config6, plugin, userConfig, errors8, pluginName, serverName) {
387774
388439
  const allMissingVars = [];
387775
388440
  const resolveValue2 = (value) => {
@@ -387859,6 +388524,7 @@ async function getPluginMcpServers(plugin, errors8 = []) {
387859
388524
  const userConfig = buildMcpUserConfig(plugin, name3);
387860
388525
  try {
387861
388526
  resolvedServers[name3] = resolvePluginMcpEnvironment(config6, plugin, userConfig, errors8, plugin.name, name3);
388527
+ registerAuthoredUnexpandedConfig(`plugin:${plugin.name}:${name3}`, buildAuthoredPluginConfig(config6, plugin));
387862
388528
  } catch (err2) {
387863
388529
  errors8?.push({
387864
388530
  type: "generic-error",
@@ -387871,6 +388537,7 @@ async function getPluginMcpServers(plugin, errors8 = []) {
387871
388537
  return addPluginScopeToServers(resolvedServers, plugin.name, plugin.source);
387872
388538
  }
387873
388539
  var init_mcpPluginIntegration = __esm(() => {
388540
+ init_redaction();
387874
388541
  init_types();
387875
388542
  init_debug();
387876
388543
  init_errors();
@@ -387901,25 +388568,6 @@ function markClaudeAiMcpConnected(name3) {
387901
388568
  function isClaudeAiMcpCurrentlyConnected(name3) {
387902
388569
  return currentlyConnectedClaudeAiMcps.has(name3);
387903
388570
  }
387904
- function shouldCountClaudeAiNeedsAuth(client8) {
387905
- if (client8.config.type !== "claudeai-proxy")
387906
- return false;
387907
- const eligible2 = client8.config.eligible;
387908
- if (eligible2 === false && !isClaudeAiMcpCurrentlyConnected(client8.name)) {
387909
- return false;
387910
- }
387911
- return hasClaudeAiMcpEverConnected(client8.name);
387912
- }
387913
- function getMcpNeedsAuthCount(clients) {
387914
- return clients.filter((client8) => {
387915
- if (client8.type !== "needs-auth")
387916
- return false;
387917
- if (client8.config.type === "claudeai-proxy") {
387918
- return shouldCountClaudeAiNeedsAuth(client8);
387919
- }
387920
- return client8.config.type !== "sse-ide" && client8.config.type !== "ws-ide";
387921
- }).length;
387922
- }
387923
388571
  var FETCH_TIMEOUT_MS = 5000, MCP_SERVERS_BETA_HEADER = "mcp-servers-2025-12-04", fetchClaudeAIMcpConfigsIfEligible, currentlyConnectedClaudeAiMcps;
387924
388572
  var init_claudeai = __esm(() => {
387925
388573
  init_axios2();
@@ -388184,18 +388832,22 @@ function mcpServerHealthStatusLabel(result) {
388184
388832
  function isUnconfiguredMcpServer(result) {
388185
388833
  return result.type === "failed" && result.errorCode === "UNCONFIGURED";
388186
388834
  }
388835
+ function formatErrorCode(errorCode) {
388836
+ const numeric = Number(errorCode);
388837
+ return errorCode === "23" ? "request timed out" : Number.isInteger(numeric) && numeric >= 100 && numeric <= 599 ? `HTTP ${errorCode}` : errorCode;
388838
+ }
388187
388839
  function getMcpServerFailureMessage(result) {
388840
+ const endpoint3 = getMcpErrorEndpoint(result.name, result.config, { detail: "origin" }, resolveUnexpandedMcpServers);
388188
388841
  const errorCode = result.errorCode;
388189
- if (errorCode && NAMED_FAILURE_ERROR_CODES.has(errorCode)) {
388190
- return result.error ?? errorCode;
388842
+ const redact = (errorText) => redactMcpErrorDetail(result.name, result.config, errorText, resolveUnexpandedMcpServers);
388843
+ if (errorCode !== undefined && NAMED_FAILURE_ERROR_CODES.has(errorCode)) {
388844
+ return result.error !== undefined ? redact(result.error) : errorCode;
388191
388845
  }
388192
388846
  if (errorCode) {
388193
- const numeric = Number(errorCode);
388194
- const message = errorCode === "23" ? "request timed out" : Number.isInteger(numeric) && numeric >= 100 && numeric <= 599 ? `HTTP ${errorCode}` : errorCode;
388195
- const url3 = "url" in result.config && typeof result.config.url === "string" ? result.config.url : null;
388196
- return url3 ? `${message} at ${url3}` : message;
388847
+ const message = formatErrorCode(errorCode);
388848
+ return endpoint3 ? `${message} at ${endpoint3}` : message;
388197
388849
  }
388198
- return result.error ?? "";
388850
+ return result.error !== undefined ? redact(result.error) : "";
388199
388851
  }
388200
388852
  function getMcpServerScopeFromToolName(toolName) {
388201
388853
  if (!isMcpTool({ name: toolName })) {
@@ -388298,7 +388950,15 @@ function getLoggingSafeMcpBaseUrl(config6) {
388298
388950
  return;
388299
388951
  }
388300
388952
  }
388301
- var NAMED_FAILURE_ERROR_CODES;
388953
+ var NAMED_FAILURE_ERROR_CODES, resolveUnexpandedMcpServers = (scope) => {
388954
+ if (scope === "dynamic") {
388955
+ const registry2 = getAuthoredUnexpandedRegistry();
388956
+ return registry2.size === 0 ? undefined : Object.fromEntries(registry2);
388957
+ }
388958
+ if (scope !== "local" && scope !== "user" && scope !== "project" && scope !== "enterprise")
388959
+ return;
388960
+ return getMcpConfigsByScope(scope, { expandVars: false }).servers;
388961
+ };
388302
388962
  var init_utils9 = __esm(() => {
388303
388963
  init_state();
388304
388964
  init_cwd2();
@@ -388308,6 +388968,7 @@ var init_utils9 = __esm(() => {
388308
388968
  init_slowOperations();
388309
388969
  init_config6();
388310
388970
  init_mcpStringUtils();
388971
+ init_redaction();
388311
388972
  init_normalization();
388312
388973
  init_types();
388313
388974
  NAMED_FAILURE_ERROR_CODES = new Set([
@@ -388383,7 +389044,7 @@ function commandArraysMatch(a5, b5) {
388383
389044
  }
388384
389045
  return a5.every((val, idx) => val === b5[idx]);
388385
389046
  }
388386
- function getServerUrl(config6) {
389047
+ function getServerUrl2(config6) {
388387
389048
  return "url" in config6 ? config6.url : null;
388388
389049
  }
388389
389050
  function unwrapCcrProxyUrl(url3) {
@@ -388403,7 +389064,7 @@ function getMcpServerSignature(config6) {
388403
389064
  if (cmd) {
388404
389065
  return `stdio:${jsonStringify(cmd)}`;
388405
389066
  }
388406
- const url3 = getServerUrl(config6);
389067
+ const url3 = getServerUrl2(config6);
388407
389068
  if (url3) {
388408
389069
  return `url:${unwrapCcrProxyUrl(url3)}`;
388409
389070
  }
@@ -388502,7 +389163,7 @@ function isMcpServerDenied(serverName, config6) {
388502
389163
  }
388503
389164
  }
388504
389165
  }
388505
- const serverUrl = getServerUrl(config6);
389166
+ const serverUrl = getServerUrl2(config6);
388506
389167
  if (serverUrl) {
388507
389168
  for (const entry of settings.deniedMcpServers) {
388508
389169
  if (isMcpServerUrlEntry(entry) && urlMatchesPattern(serverUrl, entry.serverUrl)) {
@@ -388528,7 +389189,7 @@ function isMcpServerAllowedByPolicy(serverName, config6) {
388528
389189
  const hasUrlEntries = settings.allowedMcpServers.some(isMcpServerUrlEntry);
388529
389190
  if (config6) {
388530
389191
  const serverCommand = getServerCommandArray(config6);
388531
- const serverUrl = getServerUrl(config6);
389192
+ const serverUrl = getServerUrl2(config6);
388532
389193
  if (serverCommand) {
388533
389194
  if (hasCommandEntries) {
388534
389195
  for (const entry of settings.allowedMcpServers) {
@@ -388825,7 +389486,7 @@ function getProjectMcpConfigsFromCwd() {
388825
389486
  errors: errors8 || []
388826
389487
  };
388827
389488
  }
388828
- function getMcpConfigsByScope(scope) {
389489
+ function getMcpConfigsByScope(scope, options) {
388829
389490
  const sourceMap = {
388830
389491
  project: "projectSettings",
388831
389492
  user: "userSettings",
@@ -388848,7 +389509,7 @@ function getMcpConfigsByScope(scope) {
388848
389509
  const mcpJsonPath = join80(dir, ".mcp.json");
388849
389510
  const { config: config6, errors: errors8 } = parseMcpConfigFromFilePath({
388850
389511
  filePath: mcpJsonPath,
388851
- expandVars: true,
389512
+ expandVars: options?.expandVars ?? true,
388852
389513
  scope: "project"
388853
389514
  });
388854
389515
  if (!config6) {
@@ -388878,7 +389539,7 @@ function getMcpConfigsByScope(scope) {
388878
389539
  }
388879
389540
  const { config: config6, errors: errors8 } = parseMcpConfig({
388880
389541
  configObject: { mcpServers },
388881
- expandVars: true,
389542
+ expandVars: options?.expandVars ?? true,
388882
389543
  scope: "user"
388883
389544
  });
388884
389545
  return {
@@ -388893,7 +389554,7 @@ function getMcpConfigsByScope(scope) {
388893
389554
  }
388894
389555
  const { config: config6, errors: errors8 } = parseMcpConfig({
388895
389556
  configObject: { mcpServers },
388896
- expandVars: true,
389557
+ expandVars: options?.expandVars ?? true,
388897
389558
  scope: "local"
388898
389559
  });
388899
389560
  return {
@@ -388905,7 +389566,7 @@ function getMcpConfigsByScope(scope) {
388905
389566
  const enterpriseMcpPath = getEnterpriseMcpFilePath();
388906
389567
  const { config: config6, errors: errors8 } = parseMcpConfigFromFilePath({
388907
389568
  filePath: enterpriseMcpPath,
388908
- expandVars: true,
389569
+ expandVars: options?.expandVars ?? true,
388909
389570
  scope: "enterprise"
388910
389571
  });
388911
389572
  if (!config6) {
@@ -389293,6 +389954,10 @@ function parseDynamicMcpConfig(params) {
389293
389954
  }
389294
389955
  let serverConfig = validated;
389295
389956
  if (expandVars) {
389957
+ registerAuthoredUnexpandedConfig(name3, {
389958
+ ...validated,
389959
+ scope
389960
+ });
389296
389961
  const { expanded, missingVars, urlExpandedToEmpty } = expandEnvVars(validated);
389297
389962
  if (missingVars.length > 0) {
389298
389963
  pushEntryError(name3, `Missing environment variables: ${missingVars.join(", ")}`, `Set the following environment variables: ${missingVars.join(", ")}`, undefined);
@@ -389398,6 +390063,7 @@ var init_config6 = __esm(() => {
389398
390063
  init_slowOperations();
389399
390064
  init_analytics();
389400
390065
  init_claudeai();
390066
+ init_redaction();
389401
390067
  init_types();
389402
390068
  init_utils9();
389403
390069
  init_normalization();
@@ -438905,7 +439571,8 @@ async function authStatus(opts) {
438905
439571
  const output = {
438906
439572
  loggedIn,
438907
439573
  authMethod,
438908
- apiProvider
439574
+ apiProvider,
439575
+ configDirectory: getClaudeConfigHomeDir()
438909
439576
  };
438910
439577
  if (resolvedApiKeySource) {
438911
439578
  output.apiKeySource = resolvedApiKeySource;
@@ -452939,6 +453606,15 @@ function parseRGB(colorStr) {
452939
453606
  RGB_CACHE.set(colorStr, result);
452940
453607
  return result;
452941
453608
  }
453609
+ function collapseWhitespace(value) {
453610
+ return value.replace(/\s+/g, " ").trim();
453611
+ }
453612
+ function computeTodoLabel(todo) {
453613
+ return [todo.activeForm, todo.subject].map((value) => value === undefined ? undefined : collapseWhitespace(value)).find(Boolean);
453614
+ }
453615
+ function computeSpinnerVerbWidth(columns) {
453616
+ return Math.max(40, columns - 8);
453617
+ }
452942
453618
  var THINKING_AMBER_DELAY_MS = 1e4, THINKING_AMBER_RAMP_MS = 1e4, RGB_CACHE;
452943
453619
  var init_utils10 = __esm(() => {
452944
453620
  RGB_CACHE = new Map;
@@ -459741,7 +460417,8 @@ function SpinnerWithVerbInner({
459741
460417
  const currentTodo = tasksV2?.find((task) => task.status !== "pending" && task.status !== "completed");
459742
460418
  const nextTask = findNextPendingTask(tasksV2);
459743
460419
  const [randomVerb] = import_react64.useState(() => sample_default(getSpinnerVerbs()));
459744
- const leaderVerb = overrideMessage ?? currentTodo?.activeForm ?? currentTodo?.subject ?? randomVerb;
460420
+ const leaderTodoLabel = currentTodo ? computeTodoLabel(currentTodo) : undefined;
460421
+ const leaderVerb = overrideMessage ?? (leaderTodoLabel === undefined ? undefined : truncateToWidthNoEllipsis(leaderTodoLabel, computeSpinnerVerbWidth(columns))) ?? randomVerb;
459745
460422
  const effectiveVerb = foregroundedTeammate && !foregroundedTeammate.isIdle ? foregroundedTeammate.spinnerVerb ?? randomVerb : leaderVerb;
459746
460423
  const message = effectiveVerb + "\u2026";
459747
460424
  import_react64.useEffect(() => {
@@ -459913,7 +460590,8 @@ function SpinnerWithVerbInner({
459913
460590
  (nextTask || effectiveTip) && /* @__PURE__ */ jsx_runtime82.jsx(MessageResponse, {
459914
460591
  children: /* @__PURE__ */ jsx_runtime82.jsx(ThemedText, {
459915
460592
  dimColor: true,
459916
- children: nextTask ? `Next: ${nextTask.subject}` : `Tip: ${effectiveTip}`
460593
+ wrap: nextTask ? "truncate-end" : "wrap",
460594
+ children: nextTask ? `Next: ${collapseWhitespace(nextTask.subject)}` : `Tip: ${effectiveTip}`
459917
460595
  })
459918
460596
  })
459919
460597
  ]
@@ -460263,6 +460941,7 @@ var init_Spinner2 = __esm(() => {
460263
460941
  init_useTerminalSize();
460264
460942
  init_stringWidth();
460265
460943
  init_Spinner();
460944
+ init_utils10();
460266
460945
  init_SpinnerAnimationRow();
460267
460946
  init_useSettings();
460268
460947
  init_InProcessTeammateTask();
@@ -497153,7 +497832,7 @@ function filterValue(rule, node, options) {
497153
497832
  throw new TypeError("`filter` needs to be a string, array, or function");
497154
497833
  }
497155
497834
  }
497156
- function collapseWhitespace(options) {
497835
+ function collapseWhitespace2(options) {
497157
497836
  var element = options.element;
497158
497837
  var isBlock2 = options.isBlock;
497159
497838
  var isVoid2 = options.isVoid;
@@ -497245,7 +497924,7 @@ function RootNode(input, options) {
497245
497924
  } else {
497246
497925
  root3 = input.cloneNode(true);
497247
497926
  }
497248
- collapseWhitespace({
497927
+ collapseWhitespace2({
497249
497928
  element: root3,
497250
497929
  isBlock,
497251
497930
  isVoid,
@@ -497818,6 +498497,7 @@ __export(exports_utils2, {
497818
498497
  validateURL: () => validateURL,
497819
498498
  isPreapprovedUrl: () => isPreapprovedUrl,
497820
498499
  isPermittedRedirect: () => isPermittedRedirect,
498500
+ invalidUrlErrorMessage: () => invalidUrlErrorMessage,
497821
498501
  getWithPermittedRedirects: () => getWithPermittedRedirects,
497822
498502
  getURLMarkdownContent: () => getURLMarkdownContent,
497823
498503
  getTurndownService: () => getTurndownService,
@@ -497871,6 +498551,18 @@ function validateURL(url3) {
497871
498551
  }
497872
498552
  return true;
497873
498553
  }
498554
+ function invalidUrlErrorMessage(url3) {
498555
+ let hostname4;
498556
+ try {
498557
+ hostname4 = new URL(url3).hostname;
498558
+ } catch {
498559
+ hostname4 = undefined;
498560
+ }
498561
+ if (hostname4 && !hostname4.includes(".")) {
498562
+ return "WebFetch cannot fetch localhost or other hostnames without a dot. To reach a local server, use Bash with curl instead.";
498563
+ }
498564
+ return "Invalid URL";
498565
+ }
497874
498566
  async function checkDomainBlocklist(domain2) {
497875
498567
  if (DOMAIN_CHECK_CACHE.has(domain2)) {
497876
498568
  return { status: "allowed" };
@@ -497960,7 +498652,7 @@ function isRedirectInfo(response3) {
497960
498652
  }
497961
498653
  async function getURLMarkdownContent(url3, abortController) {
497962
498654
  if (!validateURL(url3)) {
497963
- throw new Error("Invalid URL");
498655
+ throw new Error(invalidUrlErrorMessage(url3));
497964
498656
  }
497965
498657
  const cachedEntry = URL_CACHE.get(url3);
497966
498658
  if (cachedEntry) {
@@ -560902,18 +561594,18 @@ function parseFolderPath(folderPath) {
560902
561594
  }
560903
561595
  return { platform: platform5, buildId };
560904
561596
  }
560905
- var import_debug177, debugCache;
561597
+ var import_debug178, debugCache;
560906
561598
  var init_Cache = __esm(() => {
560907
561599
  init_browser_data();
560908
561600
  init_detectPlatform();
560909
- import_debug177 = __toESM(require_src(), 1);
560910
- debugCache = import_debug177.default("puppeteer:browsers:cache");
561601
+ import_debug178 = __toESM(require_src(), 1);
561602
+ debugCache = import_debug178.default("puppeteer:browsers:cache");
560911
561603
  });
560912
561604
 
560913
561605
  // node_modules/.bun/@puppeteer+browsers@2.13.2/node_modules/@puppeteer/browsers/lib/esm/debug.js
560914
- var import_debug178;
561606
+ var import_debug179;
560915
561607
  var init_debug3 = __esm(() => {
560916
- import_debug178 = __toESM(require_src(), 1);
561608
+ import_debug179 = __toESM(require_src(), 1);
560917
561609
  });
560918
561610
 
560919
561611
  // node_modules/.bun/@puppeteer+browsers@2.13.2/node_modules/@puppeteer/browsers/lib/esm/launch.js
@@ -561232,7 +561924,7 @@ var init_launch = __esm(() => {
561232
561924
  init_Cache();
561233
561925
  init_debug3();
561234
561926
  init_detectPlatform();
561235
- debugLaunch = import_debug178.default("puppeteer:browsers:launcher");
561927
+ debugLaunch = import_debug179.default("puppeteer:browsers:launcher");
561236
561928
  CDP_WEBSOCKET_ENDPOINT_REGEX = /^DevTools listening on (ws:\/\/.*)$/;
561237
561929
  WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX = /^WebDriver BiDi listening on (ws:\/\/.*)$/;
561238
561930
  processListeners = new Map;
@@ -566316,10 +567008,10 @@ async function installDMG(dmgPath, folderPath) {
566316
567008
  spawnSync4("hdiutil", ["detach", mountPath, "-quiet"]);
566317
567009
  }
566318
567010
  }
566319
- var import_debug180, debugFileUtil, internalConstantsForTesting;
567011
+ var import_debug181, debugFileUtil, internalConstantsForTesting;
566320
567012
  var init_fileUtil = __esm(() => {
566321
- import_debug180 = __toESM(require_src(), 1);
566322
- debugFileUtil = import_debug180.default("puppeteer:browsers:fileUtil");
567013
+ import_debug181 = __toESM(require_src(), 1);
567014
+ debugFileUtil = import_debug181.default("puppeteer:browsers:fileUtil");
566323
567015
  internalConstantsForTesting = {
566324
567016
  xz: "xz",
566325
567017
  bzip2: "bzip2"
@@ -566612,7 +567304,7 @@ var init_install = __esm(() => {
566612
567304
  init_fileUtil();
566613
567305
  init_httpUtil();
566614
567306
  import_progress = __toESM(require_node_progress(), 1);
566615
- debugInstall = import_debug178.default("puppeteer:browsers:install");
567307
+ debugInstall = import_debug179.default("puppeteer:browsers:install");
566616
567308
  times = new Map;
566617
567309
  });
566618
567310
 
@@ -572887,7 +573579,7 @@ import fs23 from "fs";
572887
573579
  import os16 from "os";
572888
573580
  import { dirname as dirname45 } from "path";
572889
573581
  import { PassThrough as PassThrough4 } from "stream";
572890
- var import_debug182, __runInitializers23 = function(thisArg, initializers, value) {
573582
+ var import_debug183, __runInitializers23 = function(thisArg, initializers, value) {
572891
573583
  var useValue = arguments.length > 2;
572892
573584
  for (var i6 = 0;i6 < initializers.length; i6++) {
572893
573585
  value = useValue ? initializers[i6].call(thisArg, value) : initializers[i6].call(thisArg);
@@ -572947,8 +573639,8 @@ var init_ScreenRecorder = __esm(() => {
572947
573639
  init_util6();
572948
573640
  init_decorators();
572949
573641
  init_disposable();
572950
- import_debug182 = __toESM(require_src(), 1);
572951
- debugFfmpeg = import_debug182.default("puppeteer:ffmpeg");
573642
+ import_debug183 = __toESM(require_src(), 1);
573643
+ debugFfmpeg = import_debug183.default("puppeteer:ffmpeg");
572952
573644
  ScreenRecorder = (() => {
572953
573645
  let _classSuper = PassThrough4;
572954
573646
  let _instanceExtraInitializers = [];
@@ -604992,12 +605684,8 @@ ${customInstructions}`;
604992
605684
  function formatCompactSummary(summary) {
604993
605685
  let formattedSummary = summary;
604994
605686
  formattedSummary = formattedSummary.replace(/<analysis>[\s\S]*?<\/analysis>/, "");
604995
- const summaryMatch = formattedSummary.match(/<summary>([\s\S]*?)<\/summary>/);
604996
- if (summaryMatch) {
604997
- const content = summaryMatch[1] || "";
604998
- formattedSummary = formattedSummary.replace(/<summary>[\s\S]*?<\/summary>/, `Summary:
604999
- ${content.trim()}`);
605000
- }
605687
+ formattedSummary = formattedSummary.replace(/<summary>([\s\S]*?)<\/summary>/, (_m4, g5) => `Summary:
605688
+ ${(g5 ?? "").trim()}`);
605001
605689
  formattedSummary = formattedSummary.replace(/\n\n+/g, `
605002
605690
 
605003
605691
  `);
@@ -614788,7 +615476,7 @@ function isClassifierDenial(content) {
614788
615476
  function buildYoloRejectionMessage(reason) {
614789
615477
  const prefix = AUTO_MODE_REJECTION_PREFIX;
614790
615478
  const ruleHint = feature("BASH_CLASSIFIER") ? `To allow this type of action in the future, the user can add a permission rule like ` + `Bash(prompt: <description of allowed action>) to their settings. ` + `At the end of your session, recommend what permission rules to add so you don't get blocked again.` : `To allow this type of action in the future, the user can add a Bash permission rule to their settings.`;
614791
- return `${prefix}${reason}. ` + `If you have other tasks that don't depend on this action, continue working on those. ` + `${DENIAL_WORKAROUND_GUIDANCE} ` + ruleHint;
615479
+ return `${prefix}${reason}. ` + `If you have other tasks that don't depend on this action, continue working on those. ` + `${DENIAL_WORKAROUND_GUIDANCE_BASE}${AUTO_MODE_STOP_SUFFIX} ` + ruleHint;
614792
615480
  }
614793
615481
  function buildClassifierUnavailableMessage(toolName, classifierModel) {
614794
615482
  return `${classifierModel} is temporarily unavailable, so auto mode cannot determine the safety of ${toolName} right now. ` + `Wait briefly and then try this action again. ` + `If it keeps failing, continue with other tasks that don't require this action and come back to it later. ` + `Note: reading files, searching code, and other read-only operations do not require the classifier and can still be used.`;
@@ -618189,7 +618877,7 @@ Note: The user's next message may contain a correction or preference. Pay close
618189
618877
  `, PLAN_REJECTION_PREFIX = `The agent proposed a plan that was rejected by the user. The user chose to stay in plan mode rather than proceed with implementation.
618190
618878
 
618191
618879
  Rejected plan:
618192
- `, DENIAL_WORKAROUND_GUIDANCE, NO_RESPONSE_REQUESTED = "No response requested.", SYNTHETIC_TOOL_RESULT_PLACEHOLDER = "[Tool result missing due to internal error]", AUTO_MODE_REJECTION_PREFIX = "Permission for this action was denied by the Claude Code auto mode classifier. Reason: ", CLASSIFIER_UNAVAILABLE_REASON = "Classifier unavailable", CLASSIFIER_PARSING_ERROR_REASON_PREFIX = "Auto mode could not evaluate this action and is blocking it for safety", CLASSIFIER_TRANSCRIPT_TOO_LONG_REASON = "Auto mode classifier transcript exceeded context window \u2014 falling back to manual approval (try /compact to reduce conversation size)", SYNTHETIC_MODEL = "<synthetic>", SYNTHETIC_MESSAGES, EMPTY_LOOKUPS, EMPTY_STRING_SET, _normalizationCache, STRIPPED_TAGS_RE, PLAN_PHASE4_CONTROL = `### Phase 4: Final Plan
618880
+ `, DENIAL_WORKAROUND_GUIDANCE_BASE, LEGACY_STOP_SUFFIX, AUTO_MODE_STOP_SUFFIX, DENIAL_WORKAROUND_GUIDANCE, NO_RESPONSE_REQUESTED = "No response requested.", SYNTHETIC_TOOL_RESULT_PLACEHOLDER = "[Tool result missing due to internal error]", AUTO_MODE_REJECTION_PREFIX = "Permission for this action was denied by the Claude Code auto mode classifier. Reason: ", CLASSIFIER_UNAVAILABLE_REASON = "Classifier unavailable", CLASSIFIER_PARSING_ERROR_REASON_PREFIX = "Auto mode could not evaluate this action and is blocking it for safety", CLASSIFIER_TRANSCRIPT_TOO_LONG_REASON = "Auto mode classifier transcript exceeded context window \u2014 falling back to manual approval (try /compact to reduce conversation size)", SYNTHETIC_MODEL = "<synthetic>", SYNTHETIC_MESSAGES, EMPTY_LOOKUPS, EMPTY_STRING_SET, _normalizationCache, STRIPPED_TAGS_RE, PLAN_PHASE4_CONTROL = `### Phase 4: Final Plan
618193
618881
  Goal: Write your final plan to the plan file (the only file you can edit).
618194
618882
  - Begin with a **Context** section: explain why this change is being made \u2014 the problem or need it addresses, what prompted it, and the intended outcome
618195
618883
  - Include only your recommended approach, not all alternatives
@@ -618264,7 +618952,10 @@ var init_messages3 = __esm(() => {
618264
618952
  init_stringUtils();
618265
618953
  init_tasks();
618266
618954
  init_toolSearch();
618267
- DENIAL_WORKAROUND_GUIDANCE = `IMPORTANT: You *may* attempt to accomplish this action using other tools that might naturally be used to accomplish this goal, ` + `e.g. using head instead of cat. But you *should not* attempt to work around this denial in malicious ways, ` + `e.g. do not use your ability to run tests to execute non-test actions. ` + `You should only try to work around this restriction in reasonable ways that do not attempt to bypass the intent behind this denial. ` + `If you believe this capability is essential to complete the user's request, STOP and explain to the user ` + `what you were trying to do and why you need this permission. Let the user decide how to proceed.`;
618955
+ DENIAL_WORKAROUND_GUIDANCE_BASE = `IMPORTANT: You *may* attempt to accomplish this action using other tools that might naturally be used to accomplish this goal, ` + `e.g. using head instead of cat. But you *should not* attempt to work around this denial in malicious ways, ` + `e.g. do not use your ability to run tests to execute non-test actions. ` + `You should only try to work around this restriction in reasonable ways that do not attempt to bypass the intent behind this denial. `;
618956
+ LEGACY_STOP_SUFFIX = `If you believe this capability is essential to complete the user's request, STOP and explain to the user ` + `what you were trying to do and why you need this permission. Let the user decide how to proceed.`;
618957
+ AUTO_MODE_STOP_SUFFIX = `If you believe this capability is essential to complete the user's request, first try a safer method. ` + `Get as much of the rest of the task done as you can, then STOP and explain to the user ` + `what you were trying to do and why you need this permission. Let the user decide how to proceed.`;
618958
+ DENIAL_WORKAROUND_GUIDANCE = `${DENIAL_WORKAROUND_GUIDANCE_BASE}${LEGACY_STOP_SUFFIX}`;
618268
618959
  SYNTHETIC_MESSAGES = new Set([
618269
618960
  INTERRUPT_MESSAGE,
618270
618961
  INTERRUPT_MESSAGE_FOR_TOOL_USE,
@@ -632683,7 +633374,11 @@ function should1hCacheTTL(querySource, agentCacheTtlOverride) {
632683
633374
  return resolvePromptCacheTtl(querySource, { agentCacheTtlOverride }).ttl === "1h";
632684
633375
  }
632685
633376
  function configureEffortParams(effortValue, outputConfig, extraBodyParams, betas, model) {
632686
- if (!modelSupportsEffort(model) || "effort" in outputConfig) {
633377
+ if (!modelSupportsEffort(model)) {
633378
+ delete outputConfig.effort;
633379
+ return;
633380
+ }
633381
+ if ("effort" in outputConfig) {
632687
633382
  return;
632688
633383
  }
632689
633384
  if (effortValue === undefined) {
@@ -632691,12 +633386,6 @@ function configureEffortParams(effortValue, outputConfig, extraBodyParams, betas
632691
633386
  } else if (typeof effortValue === "string") {
632692
633387
  outputConfig.effort = effortValue;
632693
633388
  betas.push(EFFORT_BETA_HEADER);
632694
- } else if (process.env.USER_TYPE === "ant") {
632695
- const existingInternal = extraBodyParams.anthropic_internal || {};
632696
- extraBodyParams.anthropic_internal = {
632697
- ...existingInternal,
632698
- effort_override: effortValue
632699
- };
632700
633389
  }
632701
633390
  }
632702
633391
  function configureTaskBudgetParams(taskBudget, outputConfig, betas) {
@@ -637288,17 +637977,23 @@ function applySettingsChange(source2, setAppState) {
637288
637977
  const prevEffort = prev.settings.effortLevel;
637289
637978
  const newEffort = newSettings.effortLevel;
637290
637979
  const effortChanged = prevEffort !== newEffort;
637980
+ const effortSyncModel = getMainLoopModel();
637981
+ const effortSyncBlocked = !modelSupportsEffort(effortSyncModel) || getEffortEnvOverride() !== undefined;
637982
+ const clampedEffort = effortSyncBlocked || newEffort === undefined ? undefined : clampEffortToCap(newEffort, effortSyncModel);
637291
637983
  return {
637292
637984
  ...prev,
637293
637985
  settings: newSettings,
637294
637986
  toolPermissionContext: newContext,
637295
- ...effortChanged && newEffort !== undefined ? { effortValue: newEffort } : {}
637987
+ ...effortChanged && clampedEffort !== undefined ? { effortValue: clampedEffort } : {}
637296
637988
  };
637297
637989
  });
637298
637990
  }
637299
637991
  var init_applySettingsChange = __esm(() => {
637300
637992
  init_debug();
637993
+ init_effort();
637994
+ init_cap();
637301
637995
  init_hooksConfigSnapshot();
637996
+ init_model();
637302
637997
  init_permissionSetup();
637303
637998
  init_permissions2();
637304
637999
  init_permissionsLoader();
@@ -646246,6 +646941,86 @@ var init_magicDocs = __esm(() => {
646246
646941
  });
646247
646942
  });
646248
646943
 
646944
+ // src/utils/mcpNeedsAuthNotice.ts
646945
+ function clearNeedsAuthNoticedThisSession() {
646946
+ needsAuthNoticedThisSession.clear();
646947
+ }
646948
+ function isFailedUnconfigured(client8) {
646949
+ return client8.type === "failed" && client8.errorCode === "UNCONFIGURED";
646950
+ }
646951
+ function isEligibleForNeedsAuthNotice(client8, { hasEverConnected, connectedThisSession }) {
646952
+ if (isFailedUnconfigured(client8))
646953
+ return false;
646954
+ if (client8.config.type === "claudeai-proxy") {
646955
+ const eligible2 = client8.config.eligible;
646956
+ if (eligible2 === false && !connectedThisSession(client8.name))
646957
+ return false;
646958
+ return hasEverConnected(client8.name);
646959
+ }
646960
+ return client8.config.type !== "sse-ide" && client8.config.type !== "ws-ide";
646961
+ }
646962
+ function shouldAnnounceNeedsAuth(client8, deps) {
646963
+ if (client8.type !== "needs-auth" || !isEligibleForNeedsAuthNotice(client8, deps)) {
646964
+ return false;
646965
+ }
646966
+ return needsAuthNoticedThisSession.has(client8.name) || !(getGlobalConfig().mcpNeedsAuthNoticed ?? []).includes(client8.name);
646967
+ }
646968
+ function countNeedsAuthToAnnounce(clients, deps) {
646969
+ let count4 = 0;
646970
+ for (const client8 of clients) {
646971
+ count4 += +!!shouldAnnounceNeedsAuth(client8, deps);
646972
+ }
646973
+ return count4;
646974
+ }
646975
+ function markNeedsAuthNoticed(clients, deps) {
646976
+ const newlyNoticed = [];
646977
+ for (const client8 of clients) {
646978
+ if (shouldAnnounceNeedsAuth(client8, deps) && !needsAuthNoticedThisSession.has(client8.name)) {
646979
+ needsAuthNoticedThisSession.add(client8.name);
646980
+ newlyNoticed.push(client8.name);
646981
+ }
646982
+ }
646983
+ if (newlyNoticed.length === 0)
646984
+ return;
646985
+ saveGlobalConfig((current) => {
646986
+ const noticed = current.mcpNeedsAuthNoticed ?? [];
646987
+ const fresh = newlyNoticed.filter((name3) => !noticed.includes(name3));
646988
+ if (fresh.length === 0)
646989
+ return current;
646990
+ const merged = [...noticed, ...fresh];
646991
+ return {
646992
+ ...current,
646993
+ mcpNeedsAuthNoticed: merged.slice(-MCP_NEEDS_AUTH_NOTICED_CAP)
646994
+ };
646995
+ });
646996
+ }
646997
+ function countNoticedServersNowConnected(clients) {
646998
+ const noticed = getGlobalConfig().mcpNeedsAuthNoticed;
646999
+ if (noticed === undefined || noticed.length === 0)
647000
+ return 0;
647001
+ let count4 = 0;
647002
+ for (const client8 of clients) {
647003
+ count4 += +!!(client8.type === "connected" && noticed.includes(client8.name));
647004
+ }
647005
+ return count4;
647006
+ }
647007
+ function pruneNoticedServersNowConnected(clients) {
647008
+ saveGlobalConfig((current) => {
647009
+ const noticed = current.mcpNeedsAuthNoticed;
647010
+ if (noticed === undefined || noticed.length === 0)
647011
+ return current;
647012
+ const remaining = noticed.filter((name3) => !clients.some((client8) => client8.name === name3 && client8.type === "connected"));
647013
+ if (remaining.length === noticed.length)
647014
+ return current;
647015
+ return { ...current, mcpNeedsAuthNoticed: remaining };
647016
+ });
647017
+ }
647018
+ var MCP_NEEDS_AUTH_NOTICED_CAP = 128, needsAuthNoticedThisSession;
647019
+ var init_mcpNeedsAuthNotice = __esm(() => {
647020
+ init_config4();
647021
+ needsAuthNoticedThisSession = new Set;
647022
+ });
647023
+
646249
647024
  // src/commands/clear/caches.ts
646250
647025
  var exports_caches = {};
646251
647026
  __export(exports_caches, {
@@ -646268,6 +647043,7 @@ function clearSessionCaches(preservedAgentIds = new Set) {
646268
647043
  resetGetMemoryFilesCache("session_start");
646269
647044
  clearStoredImagePaths();
646270
647045
  clearAllSessions();
647046
+ clearNeedsAuthNoticedThisSession();
646271
647047
  if (!hasPreserved)
646272
647048
  clearAllPendingCallbacks();
646273
647049
  if (process.env.USER_TYPE === "ant") {
@@ -646315,6 +647091,7 @@ var init_caches = __esm(() => {
646315
647091
  init_detectRepository();
646316
647092
  init_gitFilesystem();
646317
647093
  init_imageStore();
647094
+ init_mcpNeedsAuthNotice();
646318
647095
  init_sessionEnvVars();
646319
647096
  });
646320
647097
 
@@ -649457,7 +650234,7 @@ var init_EffortIndicator = __esm(() => {
649457
650234
 
649458
650235
  // src/components/ModelPicker.tsx
649459
650236
  function ModelPicker(t0) {
649460
- const $4 = import_compiler_runtime133.c(84);
650237
+ const $4 = import_compiler_runtime133.c(86);
649461
650238
  const {
649462
650239
  initial,
649463
650240
  sessionModel,
@@ -649583,6 +650360,9 @@ function ModelPicker(t0) {
649583
650360
  t8 = $4[22];
649584
650361
  }
649585
650362
  const focusedSupportsMax = t8;
650363
+ const focusedModelForCap = resolveOptionModel(focusedValue);
650364
+ const focusedCap = focusedModelForCap ? getEffectiveEffortCap(focusedModelForCap) : null;
650365
+ const focusedCapped = focusedModelForCap ? hasEffortLevelsAboveCap(focusedModelForCap) : false;
649586
650366
  let t9;
649587
650367
  if ($4[23] !== focusedValue) {
649588
650368
  t9 = getDefaultEffortLevelForOption(focusedValue);
@@ -649592,13 +650372,16 @@ function ModelPicker(t0) {
649592
650372
  t9 = $4[24];
649593
650373
  }
649594
650374
  const focusedDefaultEffort = t9;
649595
- const displayEffort = effort === "max" && !focusedSupportsMax || effort === "xhigh" && !focusedSupportsXhigh ? "high" : effort;
650375
+ const t8b = effort === "max" && !focusedSupportsMax || effort === "xhigh" && !focusedSupportsXhigh ? "high" : effort;
650376
+ const displayEffort = t8b !== undefined && focusedModelForCap ? clampEffortToCap(t8b, focusedModelForCap) : t8b;
649596
650377
  let t10;
649597
650378
  if ($4[25] !== effortValue || $4[26] !== hasToggledEffort) {
649598
650379
  t10 = (value) => {
649599
650380
  setFocusedValue(value);
649600
650381
  if (!hasToggledEffort && effortValue === undefined) {
649601
- setEffort(getDefaultEffortLevelForOption(value));
650382
+ const focusModel = resolveOptionModel(value);
650383
+ const defaultEffort = getDefaultEffortLevelForOption(value);
650384
+ setEffort(focusModel ? clampEffortToCap(defaultEffort, focusModel) : defaultEffort);
649602
650385
  }
649603
650386
  };
649604
650387
  $4[25] = effortValue;
@@ -649609,12 +650392,12 @@ function ModelPicker(t0) {
649609
650392
  }
649610
650393
  const handleFocus = t10;
649611
650394
  let t11;
649612
- if ($4[28] !== focusedDefaultEffort || $4[29] !== focusedSupportsEffort || $4[30] !== focusedSupportsMax || $4[83] !== focusedSupportsXhigh) {
650395
+ if ($4[28] !== focusedDefaultEffort || $4[29] !== focusedSupportsEffort || $4[30] !== focusedSupportsMax || $4[83] !== focusedSupportsXhigh || $4[84] !== focusedCap) {
649613
650396
  t11 = (direction) => {
649614
650397
  if (!focusedSupportsEffort) {
649615
650398
  return;
649616
650399
  }
649617
- setEffort((prev) => cycleEffortLevel(prev ?? focusedDefaultEffort, direction, focusedSupportsMax, focusedSupportsXhigh));
650400
+ setEffort((prev) => cycleEffortLevel(prev ?? focusedDefaultEffort, direction, focusedSupportsMax, focusedSupportsXhigh, focusedCap));
649618
650401
  setHasToggledEffort(true);
649619
650402
  };
649620
650403
  $4[28] = focusedDefaultEffort;
@@ -649622,6 +650405,7 @@ function ModelPicker(t0) {
649622
650405
  $4[30] = focusedSupportsMax;
649623
650406
  $4[31] = t11;
649624
650407
  $4[83] = focusedSupportsXhigh;
650408
+ $4[84] = focusedCap;
649625
650409
  } else {
649626
650410
  t11 = $4[31];
649627
650411
  }
@@ -649662,11 +650446,14 @@ function ModelPicker(t0) {
649662
650446
  let t14;
649663
650447
  if ($4[35] !== effort || $4[36] !== hasToggledEffort || $4[37] !== onSelect || $4[38] !== setAppState || $4[39] !== skipSettingsWrite) {
649664
650448
  t14 = function handleSelect2(value_0) {
650449
+ const selectedModel = resolveOptionModel(value_0);
650450
+ const clampedSelectEffort = selectedModel && effort !== undefined ? clampEffortToCap(effort, selectedModel) : effort;
649665
650451
  logEvent2("tengu_model_command_menu_effort", {
649666
- effort
650452
+ effort: clampedSelectEffort
649667
650453
  });
649668
650454
  if (!skipSettingsWrite) {
649669
- const effortLevel = resolvePickerEffortPersistence(effort, getDefaultEffortLevelForOption(value_0), getSettingsForSource("userSettings")?.effortLevel, hasToggledEffort);
650455
+ const persistModel = selectedModel ?? getDefaultMainLoopModel();
650456
+ const effortLevel = clampEffortToCap(resolvePickerEffortPersistence(effort, getDefaultEffortLevelForOption(value_0), getSettingsForSource("userSettings")?.effortLevel, hasToggledEffort), persistModel);
649670
650457
  const persistable = toPersistableEffort(effortLevel);
649671
650458
  if (persistable !== undefined) {
649672
650459
  updateSettingsForSource("userSettings", {
@@ -649678,8 +650465,7 @@ function ModelPicker(t0) {
649678
650465
  effortValue: effortLevel
649679
650466
  }));
649680
650467
  }
649681
- const selectedModel = resolveOptionModel(value_0);
649682
- const selectedEffort = hasToggledEffort && selectedModel && modelSupportsEffort(selectedModel) ? effort : undefined;
650468
+ const selectedEffort = hasToggledEffort && selectedModel && modelSupportsEffort(selectedModel) ? clampedSelectEffort : undefined;
649683
650469
  if (value_0 === NO_PREFERENCE) {
649684
650470
  onSelect(null, selectedEffort);
649685
650471
  return;
@@ -649812,42 +650598,49 @@ function ModelPicker(t0) {
649812
650598
  t23 = $4[61];
649813
650599
  }
649814
650600
  let t24;
649815
- if ($4[62] !== displayEffort || $4[63] !== focusedDefaultEffort || $4[64] !== focusedModelName || $4[65] !== focusedSupportsEffort) {
649816
- t24 = /* @__PURE__ */ jsx_runtime183.jsx(ThemedBox_default, {
650601
+ if ($4[62] !== displayEffort || $4[63] !== focusedDefaultEffort || $4[64] !== focusedModelName || $4[65] !== focusedSupportsEffort || $4[85] !== focusedCapped) {
650602
+ t24 = /* @__PURE__ */ jsx_runtime183.jsxs(ThemedBox_default, {
649817
650603
  marginBottom: 1,
649818
650604
  flexDirection: "column",
649819
- children: focusedSupportsEffort ? /* @__PURE__ */ jsx_runtime183.jsxs(ThemedText, {
649820
- dimColor: true,
649821
- children: [
649822
- /* @__PURE__ */ jsx_runtime183.jsx(EffortLevelIndicator, {
649823
- effort: displayEffort
649824
- }),
649825
- " ",
649826
- capitalize_default(displayEffort),
649827
- " effort",
649828
- displayEffort === focusedDefaultEffort ? " (default)" : "",
649829
- " ",
649830
- /* @__PURE__ */ jsx_runtime183.jsx(ThemedText, {
649831
- color: "subtle",
649832
- children: "\u2190 \u2192 to adjust"
649833
- })
649834
- ]
649835
- }) : /* @__PURE__ */ jsx_runtime183.jsxs(ThemedText, {
649836
- color: "subtle",
649837
- children: [
649838
- /* @__PURE__ */ jsx_runtime183.jsx(EffortLevelIndicator, {
649839
- effort: undefined
649840
- }),
649841
- " Effort not supported",
649842
- focusedModelName ? ` for ${focusedModelName}` : ""
649843
- ]
649844
- })
650605
+ children: [
650606
+ focusedSupportsEffort ? /* @__PURE__ */ jsx_runtime183.jsxs(ThemedText, {
650607
+ dimColor: true,
650608
+ children: [
650609
+ /* @__PURE__ */ jsx_runtime183.jsx(EffortLevelIndicator, {
650610
+ effort: displayEffort
650611
+ }),
650612
+ " ",
650613
+ capitalize_default(displayEffort),
650614
+ " effort",
650615
+ displayEffort === focusedDefaultEffort ? " (default)" : "",
650616
+ " ",
650617
+ /* @__PURE__ */ jsx_runtime183.jsx(ThemedText, {
650618
+ color: "subtle",
650619
+ children: "\u2190 \u2192 to adjust"
650620
+ })
650621
+ ]
650622
+ }) : /* @__PURE__ */ jsx_runtime183.jsxs(ThemedText, {
650623
+ color: "subtle",
650624
+ children: [
650625
+ /* @__PURE__ */ jsx_runtime183.jsx(EffortLevelIndicator, {
650626
+ effort: undefined
650627
+ }),
650628
+ " Effort not supported",
650629
+ focusedModelName ? ` for ${focusedModelName}` : ""
650630
+ ]
650631
+ }),
650632
+ focusedCapped ? /* @__PURE__ */ jsx_runtime183.jsx(ThemedText, {
650633
+ color: "subtle",
650634
+ children: "Higher effort levels are capped by your settings or organization."
650635
+ }) : null
650636
+ ]
649845
650637
  });
649846
650638
  $4[62] = displayEffort;
649847
650639
  $4[63] = focusedDefaultEffort;
649848
650640
  $4[64] = focusedModelName;
649849
650641
  $4[65] = focusedSupportsEffort;
649850
650642
  $4[66] = t24;
650643
+ $4[85] = focusedCapped;
649851
650644
  } else {
649852
650645
  t24 = $4[66];
649853
650646
  }
@@ -650031,8 +650824,9 @@ function EffortLevelIndicator(t0) {
650031
650824
  }
650032
650825
  return t4;
650033
650826
  }
650034
- function cycleEffortLevel(current, direction, includeMax, includeXhigh) {
650035
- const levels = ["low", "medium", "high", "xhigh", "max"].filter((level) => (level !== "max" || includeMax) && (level !== "xhigh" || includeXhigh));
650827
+ function cycleEffortLevel(current, direction, includeMax, includeXhigh, cap) {
650828
+ const capIndex = cap !== undefined && cap !== null ? EFFORT_LEVEL_ORDER.indexOf(cap) : EFFORT_LEVEL_ORDER.length - 1;
650829
+ const levels = EFFORT_LEVEL_ORDER.filter((level, index2) => index2 <= capIndex && (level !== "max" || includeMax) && (level !== "xhigh" || includeXhigh));
650036
650830
  const clamped = current === "max" && !includeMax || current === "xhigh" && !includeXhigh ? "high" : current;
650037
650831
  const idx = levels.indexOf(clamped);
650038
650832
  const currentIndex = idx !== -1 ? idx : levels.length - 1;
@@ -650047,7 +650841,7 @@ function getDefaultEffortLevelForOption(value) {
650047
650841
  const defaultValue = getDefaultEffortForModel(resolved);
650048
650842
  return defaultValue !== undefined ? convertEffortValueToLevel(defaultValue) : "high";
650049
650843
  }
650050
- var import_compiler_runtime133, import_react103, jsx_runtime183, NO_PREFERENCE = "__NO_PREFERENCE__";
650844
+ var import_compiler_runtime133, import_react103, jsx_runtime183, NO_PREFERENCE = "__NO_PREFERENCE__", EFFORT_LEVEL_ORDER;
650051
650845
  var init_ModelPicker = __esm(() => {
650052
650846
  init_capitalize();
650053
650847
  init_useExitOnCtrlCDWithKeybindings();
@@ -650057,6 +650851,7 @@ var init_ModelPicker = __esm(() => {
650057
650851
  init_useKeybinding();
650058
650852
  init_AppState();
650059
650853
  init_effort();
650854
+ init_cap();
650060
650855
  init_model();
650061
650856
  init_modelOptions();
650062
650857
  init_settings2();
@@ -650069,6 +650864,7 @@ var init_ModelPicker = __esm(() => {
650069
650864
  import_compiler_runtime133 = __toESM(require_compiler_runtime(), 1);
650070
650865
  import_react103 = __toESM(require_react(), 1);
650071
650866
  jsx_runtime183 = __toESM(require_jsx_runtime(), 1);
650867
+ EFFORT_LEVEL_ORDER = ["low", "medium", "high", "xhigh", "max"];
650072
650868
  });
650073
650869
 
650074
650870
  // src/components/ClaudeMdExternalIncludesDialog.tsx
@@ -668610,6 +669406,12 @@ function MCPRemoteServerMenu({
668610
669406
  } = useTerminalSize();
668611
669407
  const [isAuthenticating, setIsAuthenticating] = import_react131.default.useState(false);
668612
669408
  const [error52, setError] = import_react131.default.useState(null);
669409
+ const scopedConfig = import_react131.default.useMemo(() => ({
669410
+ ...server.config,
669411
+ scope: server.scope ?? server.config.scope
669412
+ }), [server.config, server.scope]);
669413
+ const displayConfig = import_react131.default.useMemo(() => getDisplayConfig(server.name, scopedConfig, resolveUnexpandedMcpServers), [server.name, scopedConfig]);
669414
+ const displayUrl = "url" in displayConfig ? displayConfig.url : "";
668613
669415
  const mcp = useAppState((s4) => s4.mcp);
668614
669416
  const setAppState = useSetAppState();
668615
669417
  const [authorizationUrl, setAuthorizationUrl] = import_react131.default.useState(null);
@@ -668822,7 +669624,7 @@ function MCPRemoteServerMenu({
668822
669624
  }
668823
669625
  } catch (err_1) {
668824
669626
  if (err_1 instanceof Error && !(err_1 instanceof AuthenticationCancelledError)) {
668825
- setError(err_1.message);
669627
+ setError(redactMcpErrorDetail(server.name, scopedConfig, err_1.message, resolveUnexpandedMcpServers));
668826
669628
  }
668827
669629
  } finally {
668828
669630
  setIsAuthenticating(false);
@@ -669340,7 +670142,7 @@ function MCPRemoteServerMenu({
669340
670142
  }),
669341
670143
  /* @__PURE__ */ jsx_runtime238.jsx(ThemedText, {
669342
670144
  dimColor: true,
669343
- children: server.config.url
670145
+ children: displayUrl
669344
670146
  })
669345
670147
  ]
669346
670148
  }),
@@ -669494,6 +670296,7 @@ var init_MCPRemoteServerMenu = __esm(() => {
669494
670296
  init_auth11();
669495
670297
  init_client12();
669496
670298
  init_MCPConnectionManager();
670299
+ init_redaction();
669497
670300
  init_utils9();
669498
670301
  init_AppState();
669499
670302
  init_auth6();
@@ -669527,6 +670330,12 @@ function MCPStdioServerMenu({
669527
670330
  const reconnectMcpServer = useMcpReconnect();
669528
670331
  const toggleMcpServer = useMcpToggleEnabled();
669529
670332
  const [isReconnecting, setIsReconnecting] = import_react132.useState(false);
670333
+ const displayConfig = import_react132.default.useMemo(() => getDisplayConfig(server.name, {
670334
+ ...server.config,
670335
+ scope: server.config.scope ?? "dynamic"
670336
+ }, resolveUnexpandedMcpServers), [server.name, server.config]);
670337
+ const displayCommand = "command" in displayConfig ? displayConfig.command : "";
670338
+ const displayArgs = "command" in displayConfig && Array.isArray(displayConfig.args) ? displayConfig.args : [];
669530
670339
  const handleToggleEnabled = import_react132.default.useCallback(async () => {
669531
670340
  const wasEnabled = server.client.type !== "disabled";
669532
670341
  try {
@@ -669662,11 +670471,11 @@ function MCPStdioServerMenu({
669662
670471
  }),
669663
670472
  /* @__PURE__ */ jsx_runtime239.jsx(ThemedText, {
669664
670473
  dimColor: true,
669665
- children: server.config.command
670474
+ children: displayCommand
669666
670475
  })
669667
670476
  ]
669668
670477
  }),
669669
- server.config.args && server.config.args.length > 0 && /* @__PURE__ */ jsx_runtime239.jsxs(ThemedBox_default, {
670478
+ displayArgs.length > 0 && /* @__PURE__ */ jsx_runtime239.jsxs(ThemedBox_default, {
669670
670479
  children: [
669671
670480
  /* @__PURE__ */ jsx_runtime239.jsx(ThemedText, {
669672
670481
  bold: true,
@@ -669674,7 +670483,7 @@ function MCPStdioServerMenu({
669674
670483
  }),
669675
670484
  /* @__PURE__ */ jsx_runtime239.jsx(ThemedText, {
669676
670485
  dimColor: true,
669677
- children: server.config.args.join(" ")
670486
+ children: displayArgs.join(" ")
669678
670487
  })
669679
670488
  ]
669680
670489
  }),
@@ -669784,6 +670593,7 @@ var init_MCPStdioServerMenu = __esm(() => {
669784
670593
  init_ink2();
669785
670594
  init_config6();
669786
670595
  init_MCPConnectionManager();
670596
+ init_redaction();
669787
670597
  init_utils9();
669788
670598
  init_AppState();
669789
670599
  init_errors();
@@ -678987,7 +679797,7 @@ function formatZodErrors(zodError) {
678987
679797
  }));
678988
679798
  }
678989
679799
  function checkPathTraversal(p4, field, errors8, hint) {
678990
- if (p4.includes("..")) {
679800
+ if (p4.split(/[\\/]/).some((segment2) => segment2 === "..")) {
678991
679801
  errors8.push({
678992
679802
  path: field,
678993
679803
  message: hint ? `Path contains "..": ${p4}. ${hint}` : `Path contains ".." which could be a path traversal attempt: ${p4}`
@@ -716431,6 +717241,19 @@ __export(exports_effort, {
716431
717241
  call: () => call82
716432
717242
  });
716433
717243
  function setEffortValue(effortValue) {
717244
+ const model = getMainLoopModel();
717245
+ const clamped = typeof effortValue === "string" ? clampEffortToCap(effortValue, model) : effortValue;
717246
+ if (clamped !== effortValue) {
717247
+ logEvent2("tengu_effort_command", {
717248
+ effort: effortValue
717249
+ });
717250
+ return {
717251
+ message: `Effort '${effortValue}' exceeds the cap for ${model} set by your settings or organization; set to '${clamped}' instead (this session only): ${getEffortValueDescription(clamped)}`,
717252
+ effortUpdate: {
717253
+ value: clamped
717254
+ }
717255
+ };
717256
+ }
716434
717257
  const persistable = toPersistableEffort(effortValue);
716435
717258
  if (persistable !== undefined) {
716436
717259
  const result = updateSettingsForSource("userSettings", {
@@ -716481,9 +717304,10 @@ function showCurrentEffort(appStateEffort, model) {
716481
717304
  message: `Effort level: auto (currently ${level})`
716482
717305
  };
716483
717306
  }
716484
- const description = getEffortValueDescription(effectiveValue);
717307
+ const clamped = clampEffortToCap(effectiveValue, model);
717308
+ const description = getEffortValueDescription(clamped);
716485
717309
  return {
716486
- message: `Current effort level: ${effectiveValue} (${description})`
717310
+ message: `Current effort level: ${clamped} (${description})`
716487
717311
  };
716488
717312
  }
716489
717313
  function unsetEffortLevel() {
@@ -716515,7 +717339,17 @@ function unsetEffortLevel() {
716515
717339
  }
716516
717340
  };
716517
717341
  }
716518
- function enableUltracode() {
717342
+ function enableUltracode(model) {
717343
+ if (modelSupportsXhighEffort(model) && !isEffortLevelAllowed("xhigh", model)) {
717344
+ return {
717345
+ message: `Ultracode runs at xhigh effort, which is above the effort cap for ${model} set by your settings or organization. Valid options are: ${formatEffortValidOptions(model)}`
717346
+ };
717347
+ }
717348
+ if (!isUltracodeAvailableForModel(model)) {
717349
+ return {
717350
+ message: `Ultracode runs at xhigh effort, which ${model} doesn't support \u2014 switch to an xhigh-capable model (${XHIGH_CAPABLE_MODELS_HINT}). Valid options are: ${formatEffortValidOptions(model)}`
717351
+ };
717352
+ }
716519
717353
  enableUltracodeForSession();
716520
717354
  logEvent2("tengu_effort_command", {
716521
717355
  effort: "ultracode"
@@ -716537,11 +717371,11 @@ function executeEffort(args) {
716537
717371
  return unsetEffortLevel();
716538
717372
  }
716539
717373
  if (normalized === "ultracode") {
716540
- return enableUltracode();
717374
+ return enableUltracode(getMainLoopModel());
716541
717375
  }
716542
717376
  if (!isEffortLevel(normalized)) {
716543
717377
  return {
716544
- message: `Invalid argument: ${args}. Valid options are: low, medium, high, xhigh, max, ultracode, auto`
717378
+ message: `Invalid argument: ${args}. Valid options are: ${formatEffortValidOptions(getMainLoopModel())}`
716545
717379
  };
716546
717380
  }
716547
717381
  if (isUltracodeEnabled()) {
@@ -716604,14 +717438,17 @@ function ApplyEffortAndClose(t0) {
716604
717438
  async function call82(onDone, _context, args) {
716605
717439
  args = args?.trim() || "";
716606
717440
  if (COMMON_HELP_ARGS2.includes(args)) {
716607
- onDone(`Usage: /effort [low|medium|high|xhigh|max|ultracode|auto]
716608
- ` + `- low: Quick, straightforward implementation
716609
- ` + `- medium: Balanced approach with standard testing
716610
- ` + `- high: Comprehensive implementation with extensive testing
716611
- ` + `- xhigh: Extended reasoning with thorough analysis (Fable 5, Opus 4.7+, Sonnet 5)
716612
- ` + `- max: Maximum capability with deepest reasoning (Fable 5, Opus 4.6+, Sonnet 4.6+)
716613
- ` + `- ultracode: xhigh + dynamic workflow orchestration (this session only)
716614
- ` + "- auto: Use the default effort level for your model");
717441
+ const model = getMainLoopModel();
717442
+ const lines2 = [buildEffortArgumentHint("Usage: /effort [", "]", model)];
717443
+ for (const level of getAllowedEffortLevels(model)) {
717444
+ lines2.push(`- ${level}: ${SHORT_EFFORT_HELP[level]}`);
717445
+ }
717446
+ if (isUltracodeAvailableForModel(model)) {
717447
+ lines2.push("- ultracode: xhigh + dynamic workflow orchestration (this session only)");
717448
+ }
717449
+ lines2.push("- auto: Use the default effort level for your model");
717450
+ onDone(lines2.join(`
717451
+ `));
716615
717452
  return;
716616
717453
  }
716617
717454
  if (!args || args === "current" || args === "status") {
@@ -716625,29 +717462,42 @@ async function call82(onDone, _context, args) {
716625
717462
  onDone
716626
717463
  });
716627
717464
  }
716628
- var import_compiler_runtime248, React108, jsx_runtime350, COMMON_HELP_ARGS2;
717465
+ var import_compiler_runtime248, React108, jsx_runtime350, COMMON_HELP_ARGS2, XHIGH_CAPABLE_MODELS_HINT = "Fable 5, Opus 4.7+, Sonnet 5", SHORT_EFFORT_HELP;
716629
717466
  var init_effort2 = __esm(() => {
716630
717467
  init_useMainLoopModel();
716631
717468
  init_analytics();
716632
717469
  init_AppState();
716633
717470
  init_effort();
717471
+ init_cap();
716634
717472
  init_ultracode();
717473
+ init_model();
716635
717474
  init_settings2();
716636
717475
  import_compiler_runtime248 = __toESM(require_compiler_runtime(), 1);
716637
717476
  React108 = __toESM(require_react(), 1);
716638
717477
  jsx_runtime350 = __toESM(require_jsx_runtime(), 1);
716639
717478
  COMMON_HELP_ARGS2 = ["help", "-h", "--help"];
717479
+ SHORT_EFFORT_HELP = {
717480
+ low: "Quick, straightforward implementation",
717481
+ medium: "Balanced approach with standard testing",
717482
+ high: "Comprehensive implementation with extensive testing",
717483
+ xhigh: "Extended reasoning with thorough analysis (Fable 5, Opus 4.7+, Sonnet 5)",
717484
+ max: "Maximum capability with deepest reasoning (Fable 5, Opus 4.6+, Sonnet 4.6+)"
717485
+ };
716640
717486
  });
716641
717487
 
716642
717488
  // src/commands/effort/index.ts
716643
717489
  var effort_default;
716644
717490
  var init_effort3 = __esm(() => {
717491
+ init_cap();
716645
717492
  init_immediateCommand();
717493
+ init_model();
716646
717494
  effort_default = {
716647
717495
  type: "local-jsx",
716648
717496
  name: "effort",
716649
717497
  description: "Set effort level for model usage",
716650
- argumentHint: "[low|medium|high|xhigh|max|ultracode|auto]",
717498
+ get argumentHint() {
717499
+ return buildEffortArgumentHint("[", "]", getMainLoopModel());
717500
+ },
716651
717501
  get immediate() {
716652
717502
  return shouldInferenceConfigCommandBeImmediate();
716653
717503
  },
@@ -725952,7 +726802,15 @@ function stripNonLoadedContent(raw) {
725952
726802
  }
725953
726803
  return result;
725954
726804
  }
725955
- function truncateEntrypointContent(raw) {
726805
+ function truncatePreviewAtWordBoundary(value, max2) {
726806
+ if (value.length <= max2)
726807
+ return value;
726808
+ const head = sliceHead(value, max2 - 1);
726809
+ const lastWordStart = head.search(/\s\S*$/);
726810
+ const beforeLastWord = lastWordStart === -1 ? "" : head.slice(0, lastWordStart).trimEnd();
726811
+ return `${beforeLastWord.length > max2 / 2 ? beforeLastWord : head.trimEnd()}\u2026`;
726812
+ }
726813
+ function truncateEntrypointContent(raw, kind = "index") {
725956
726814
  const trimmed = raw.trim();
725957
726815
  const contentLines = trimmed.split(`
725958
726816
  `);
@@ -725976,11 +726834,20 @@ function truncateEntrypointContent(raw) {
725976
726834
  `, MAX_ENTRYPOINT_BYTES);
725977
726835
  truncated = truncated.slice(0, cutAt > 0 ? cutAt : MAX_ENTRYPOINT_BYTES);
725978
726836
  }
725979
- const reason = wasByteTruncated && !wasLineTruncated ? `${formatFileSize(byteCount)} (limit: ${formatFileSize(MAX_ENTRYPOINT_BYTES)}) \u2014 index entries are too long` : wasLineTruncated && !wasByteTruncated ? `${lineCount} lines (limit: ${MAX_ENTRYPOINT_LINES})` : `${lineCount} lines and ${formatFileSize(byteCount)}`;
726837
+ const fullLinesKept = trimmed[truncated.length] === `
726838
+ ` ? countCharInString(truncated, `
726839
+ `) + 1 : 0;
726840
+ const previewStart = truncated.length + 1;
726841
+ const previewEnd = trimmed.indexOf(`
726842
+ `, previewStart);
726843
+ const firstCutLine = trimmed.slice(previewStart, previewEnd < 0 ? undefined : previewEnd).trim();
726844
+ const cutDetail = fullLinesKept === 0 ? `everything after the first ${truncated.length} characters of line 1 was cut off` : `${lineCount - fullLinesKept} of ${lineCount} lines were cut off, starting at line ${fullLinesKept + 1}${firstCutLine ? ` ("${truncatePreviewAtWordBoundary(firstCutLine, CUT_LINE_PREVIEW_MAX)}")` : ""}`;
726845
+ const reason = wasByteTruncated && !wasLineTruncated ? `${formatFileSize(byteCount)} (limit: ${formatFileSize(MAX_ENTRYPOINT_BYTES)}) \u2014 ${kind === "index" ? "index entries are too long" : "its lines are too long"}` : wasLineTruncated && !wasByteTruncated ? `${lineCount} lines (limit: ${MAX_ENTRYPOINT_LINES})` : `${lineCount} lines and ${formatFileSize(byteCount)}`;
726846
+ const warning = kind === "index" ? `${ENTRYPOINT_NAME} is ${reason}. Only part of it was loaded: ${cutDetail}. Keep index entries to one line under ~200 chars; move detail into topic files.` : `this memory file is ${reason}. Only part of it was loaded: ${cutDetail}. Keep each memory file focused on one topic.`;
725980
726847
  return {
725981
726848
  content: truncated + `
725982
726849
 
725983
- > WARNING: ${ENTRYPOINT_NAME} is ${reason}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files.`,
726850
+ > WARNING: ${warning}`,
725984
726851
  lineCount,
725985
726852
  byteCount,
725986
726853
  wasLineTruncated,
@@ -726297,7 +727164,7 @@ async function loadMemoryPrompt() {
726297
727164
  }
726298
727165
  return null;
726299
727166
  }
726300
- var teamMemPaths7, ENTRYPOINT_NAME = "MEMORY.md", MAX_ENTRYPOINT_LINES = 200, MAX_ENTRYPOINT_BYTES = 25000, AUTO_MEM_DISPLAY_NAME = "auto memory", HTML_COMMENT_REGEX, MEMORY_INDEX_APPROACHING_THRESHOLD = 0.8, MEMORY_INDEX_TARGET_FRACTION = 0.7, WRITE_GUARD_READ_LIMIT, teamMemPrompts, DIR_EXISTS_GUIDANCE = "This directory already exists \u2014 write to it directly with the Write tool (do not run mkdir or check for its existence).", DIRS_EXIST_GUIDANCE = "Both directories already exist \u2014 write to them directly with the Write tool (do not run mkdir or check for their existence).";
727167
+ var teamMemPaths7, ENTRYPOINT_NAME = "MEMORY.md", MAX_ENTRYPOINT_LINES = 200, MAX_ENTRYPOINT_BYTES = 25000, AUTO_MEM_DISPLAY_NAME = "auto memory", HTML_COMMENT_REGEX, CUT_LINE_PREVIEW_MAX = 80, MEMORY_INDEX_APPROACHING_THRESHOLD = 0.8, MEMORY_INDEX_TARGET_FRACTION = 0.7, WRITE_GUARD_READ_LIMIT, teamMemPrompts, DIR_EXISTS_GUIDANCE = "This directory already exists \u2014 write to it directly with the Write tool (do not run mkdir or check for its existence).", DIRS_EXIST_GUIDANCE = "Both directories already exist \u2014 write to them directly with the Write tool (do not run mkdir or check for their existence).";
726301
727168
  var init_memdir = __esm(() => {
726302
727169
  init_featureFlags();
726303
727170
  init_marked_esm();
@@ -726315,6 +727182,8 @@ var init_memdir = __esm(() => {
726315
727182
  init_format();
726316
727183
  init_sessionStorage();
726317
727184
  init_settings2();
727185
+ init_stringUtils();
727186
+ init_truncateMiddle();
726318
727187
  init_memoryTypes();
726319
727188
  teamMemPaths7 = feature("TEAMMEM") ? (init_teamMemPaths(), __toCommonJS(exports_teamMemPaths)) : null;
726320
727189
  HTML_COMMENT_REGEX = /<!--[\s\S]*?-->/g;
@@ -726393,10 +727262,108 @@ var init_agentMemory = __esm(() => {
726393
727262
  init_path2();
726394
727263
  });
726395
727264
 
727265
+ // src/utils/permissions/symlinkEquivalences.ts
727266
+ import { posix as posix8 } from "path";
727267
+ function unescapePatternSegment(segment2) {
727268
+ return segment2.replace(/\\([\s\S])/g, (match, char) => ESCAPABLE_PATTERN_CHAR.test(char) ? char : match);
727269
+ }
727270
+ function escapePatternPath(path39) {
727271
+ let escaped = path39.replaceAll("\\", "\\\\").replace(/[[\]()|+^$]/g, (char) => `\\${char}`);
727272
+ escaped = escaped.replaceAll("*", "\\*");
727273
+ if (escaped.startsWith("!") || escaped.startsWith("#")) {
727274
+ escaped = `\\${escaped}`;
727275
+ }
727276
+ return escaped.replace(/\s+$/, (whitespace) => Array.from(whitespace, (char) => `\\${char}`).join(""));
727277
+ }
727278
+ function collapsePatternSlashes(pattern) {
727279
+ const collapsed = pattern.replace(/\/{2,}/g, "/");
727280
+ if (/^\s*(?:\/\*\*)?$/.test(collapsed)) {
727281
+ return collapsed;
727282
+ }
727283
+ return collapsed.replace(/^\uFEFF([!#]?)/, (_match, marker) => marker ? `\\${marker}` : "").replace(/^\uFEFF/, "[\uFEFF]");
727284
+ }
727285
+ function normalizeTrailingGlobstar(pattern, isAllow) {
727286
+ if (pattern.endsWith("/**")) {
727287
+ const withoutSuffix = pattern.slice(0, -3);
727288
+ if (/[^/]/.test(withoutSuffix)) {
727289
+ return withoutSuffix.includes("/") || !isAllow || /^[!#]/.test(withoutSuffix) ? withoutSuffix : `/${withoutSuffix}`;
727290
+ }
727291
+ return "/**";
727292
+ }
727293
+ return pattern;
727294
+ }
727295
+ function unusablePatternReason(pattern) {
727296
+ if (UNUSABLE_IGNORE_PATTERN.test(pattern)) {
727297
+ return "skipped by the ignore library (blank, comment, or trailing backslash)";
727298
+ }
727299
+ return validateIgnorePattern(pattern);
727300
+ }
727301
+ function makePhysicalTwinsKey(root3, pattern) {
727302
+ return `${root3}\x00${pattern}`;
727303
+ }
727304
+ function getOrInitPhysicalTwins(key4) {
727305
+ let twins = physicalTwinsByPattern.get(key4);
727306
+ if (twins === undefined) {
727307
+ twins = new Set;
727308
+ physicalTwinsByPattern.set(key4, twins);
727309
+ }
727310
+ return twins;
727311
+ }
727312
+ function resolvePhysicalTwinPattern(root3, rawPattern) {
727313
+ if (getPlatform() === "windows") {
727314
+ return null;
727315
+ }
727316
+ const pattern = collapsePatternSlashes(rawPattern);
727317
+ if (!pattern.startsWith("/")) {
727318
+ return null;
727319
+ }
727320
+ const segments = pattern.slice(1).split("/");
727321
+ let prefixEnd = 0;
727322
+ while (prefixEnd < segments.length && segments[prefixEnd] !== "" && !UNESCAPED_GLOB_CHAR.test(segments[prefixEnd])) {
727323
+ prefixEnd++;
727324
+ }
727325
+ if (prefixEnd === 0) {
727326
+ return null;
727327
+ }
727328
+ const prefixPath = posix8.join(root3, ...segments.slice(0, prefixEnd).map(unescapePatternSegment));
727329
+ let physicalPrefix;
727330
+ try {
727331
+ physicalPrefix = resolveDeepestExistingAncestorSync(getFsImplementation(), prefixPath);
727332
+ } catch (error52) {
727333
+ logForDebugging(`Could not resolve the physical twin of rule prefix ${prefixPath}: ${error52}`);
727334
+ return null;
727335
+ }
727336
+ if (physicalPrefix === undefined || physicalPrefix === prefixPath || physicalPrefix === DIR_SEP) {
727337
+ return null;
727338
+ }
727339
+ const rest = segments.slice(prefixEnd);
727340
+ const twin = collapsePatternSlashes(escapePatternPath(physicalPrefix) + (rest.length > 0 ? `/${rest.join("/")}` : ""));
727341
+ const normalized = normalizeTrailingGlobstar(twin, false);
727342
+ if (unusablePatternReason(normalized) !== null) {
727343
+ return null;
727344
+ }
727345
+ if (normalized !== twin && `${normalized}/**` !== twin) {
727346
+ return null;
727347
+ }
727348
+ return twin;
727349
+ }
727350
+ var DIR_SEP, UNESCAPED_GLOB_CHAR, ESCAPABLE_PATTERN_CHAR, UNUSABLE_IGNORE_PATTERN, physicalTwinsByPattern;
727351
+ var init_symlinkEquivalences = __esm(() => {
727352
+ init_debug();
727353
+ init_fsOperations();
727354
+ init_globPatternValidation();
727355
+ init_platform2();
727356
+ DIR_SEP = posix8.sep;
727357
+ UNESCAPED_GLOB_CHAR = /(?:^|[^\\])(?:\\\\)*[*?[]/;
727358
+ ESCAPABLE_PATTERN_CHAR = /^[\\[\]!#()|+^$*?\s]$/;
727359
+ UNUSABLE_IGNORE_PATTERN = /^\s*$|^#|(?:^|[^\\])\\$/;
727360
+ physicalTwinsByPattern = new Map;
727361
+ });
727362
+
726396
727363
  // src/utils/permissions/filesystem.ts
726397
727364
  import { randomBytes as randomBytes19 } from "crypto";
726398
727365
  import { homedir as homedir44, tmpdir as tmpdir15 } from "os";
726399
- import { join as join164, normalize as normalize18, posix as posix8, sep as sep47 } from "path";
727366
+ import { join as join164, normalize as normalize18, posix as posix9, sep as sep47 } from "path";
726400
727367
  function normalizeCaseForComparison2(path39) {
726401
727368
  return path39.toLowerCase();
726402
727369
  }
@@ -726439,9 +727406,9 @@ function relativePath(from2, to) {
726439
727406
  if (getPlatform() === "windows") {
726440
727407
  const posixFrom = windowsPathToPosixPath(from2);
726441
727408
  const posixTo = windowsPathToPosixPath(to);
726442
- return posix8.relative(posixFrom, posixTo);
727409
+ return posix9.relative(posixFrom, posixTo);
726443
727410
  }
726444
- return posix8.relative(from2, to);
727411
+ return posix9.relative(from2, to);
726445
727412
  }
726446
727413
  function toPosixPath(path39) {
726447
727414
  if (getPlatform() === "windows") {
@@ -726636,7 +727603,7 @@ function pathInWorkingPath(path39, workingPath) {
726636
727603
  if (containsPathTraversal(relative32)) {
726637
727604
  return false;
726638
727605
  }
726639
- return !posix8.isAbsolute(relative32);
727606
+ return !posix9.isAbsolute(relative32);
726640
727607
  }
726641
727608
  function rootPathForSource(source2) {
726642
727609
  switch (source2) {
@@ -726653,25 +727620,25 @@ function rootPathForSource(source2) {
726653
727620
  }
726654
727621
  }
726655
727622
  function prependDirSep(path39) {
726656
- return posix8.join(DIR_SEP, path39);
727623
+ return posix9.join(DIR_SEP2, path39);
726657
727624
  }
726658
727625
  function normalizePatternToPath({
726659
727626
  patternRoot,
726660
727627
  pattern,
726661
727628
  rootPath
726662
727629
  }) {
726663
- const fullPattern = posix8.join(patternRoot, pattern);
727630
+ const fullPattern = posix9.join(patternRoot, pattern);
726664
727631
  if (patternRoot === rootPath) {
726665
727632
  return prependDirSep(pattern);
726666
- } else if (fullPattern.startsWith(`${rootPath}${DIR_SEP}`)) {
727633
+ } else if (fullPattern.startsWith(`${rootPath}${DIR_SEP2}`)) {
726667
727634
  const relativePart = fullPattern.slice(rootPath.length);
726668
727635
  return prependDirSep(relativePart);
726669
727636
  } else {
726670
- const relativePath2 = posix8.relative(rootPath, patternRoot);
726671
- if (!relativePath2 || relativePath2.startsWith(`..${DIR_SEP}`) || relativePath2 === "..") {
727637
+ const relativePath2 = posix9.relative(rootPath, patternRoot);
727638
+ if (!relativePath2 || relativePath2.startsWith(`..${DIR_SEP2}`) || relativePath2 === "..") {
726672
727639
  return null;
726673
727640
  } else {
726674
- const relativePattern = posix8.join(relativePath2, pattern);
727641
+ const relativePattern = posix9.join(relativePath2, pattern);
726675
727642
  return prependDirSep(relativePattern);
726676
727643
  }
726677
727644
  }
@@ -726704,7 +727671,7 @@ function getFileReadIgnorePatterns(toolPermissionContext) {
726704
727671
  return result;
726705
727672
  }
726706
727673
  function patternWithRoot(pattern, source2) {
726707
- if (pattern.startsWith(`${DIR_SEP}${DIR_SEP}`)) {
727674
+ if (pattern.startsWith(`${DIR_SEP2}${DIR_SEP2}`)) {
726708
727675
  const patternWithoutDoubleSlash = pattern.slice(1);
726709
727676
  if (getPlatform() === "windows" && patternWithoutDoubleSlash.match(/^\/[a-z]\//i)) {
726710
727677
  const driveLetter = patternWithoutDoubleSlash[1]?.toUpperCase() ?? "C";
@@ -726718,21 +727685,21 @@ function patternWithRoot(pattern, source2) {
726718
727685
  }
726719
727686
  return {
726720
727687
  relativePattern: patternWithoutDoubleSlash,
726721
- root: DIR_SEP
727688
+ root: DIR_SEP2
726722
727689
  };
726723
- } else if (pattern.startsWith(`~${DIR_SEP}`)) {
727690
+ } else if (pattern.startsWith(`~${DIR_SEP2}`)) {
726724
727691
  return {
726725
727692
  relativePattern: pattern.slice(1),
726726
727693
  root: homedir44().normalize("NFC")
726727
727694
  };
726728
- } else if (pattern.startsWith(DIR_SEP)) {
727695
+ } else if (pattern.startsWith(DIR_SEP2)) {
726729
727696
  return {
726730
727697
  relativePattern: pattern,
726731
727698
  root: rootPathForSource(source2)
726732
727699
  };
726733
727700
  }
726734
727701
  let normalizedPattern = pattern;
726735
- if (pattern.startsWith(`.${DIR_SEP}`)) {
727702
+ if (pattern.startsWith(`.${DIR_SEP2}`)) {
726736
727703
  normalizedPattern = pattern.slice(2);
726737
727704
  }
726738
727705
  return {
@@ -726822,6 +727789,24 @@ function getPatternsByRoot(toolPermissionContext, toolType, behavior) {
726822
727789
  patternsByRoot.set(root3, patternsForRoot);
726823
727790
  }
726824
727791
  patternsForRoot.set(relativePattern, rule);
727792
+ if (behavior === "allow" || root3 === null) {
727793
+ continue;
727794
+ }
727795
+ const twins = getOrInitPhysicalTwins(makePhysicalTwinsKey(root3, relativePattern));
727796
+ const twin = resolvePhysicalTwinPattern(root3, relativePattern);
727797
+ if (twin !== null) {
727798
+ twins.add(twin);
727799
+ }
727800
+ for (const twinPattern of twins) {
727801
+ let rootSlashPatterns = patternsByRoot.get(DIR_SEP2);
727802
+ if (rootSlashPatterns === undefined) {
727803
+ rootSlashPatterns = new Map;
727804
+ patternsByRoot.set(DIR_SEP2, rootSlashPatterns);
727805
+ }
727806
+ if (!rootSlashPatterns.has(twinPattern)) {
727807
+ rootSlashPatterns.set(twinPattern, rule);
727808
+ }
727809
+ }
726825
727810
  }
726826
727811
  return patternsByRoot;
726827
727812
  }
@@ -726834,7 +727819,7 @@ function matchingRuleForInput(path39, toolPermissionContext, toolType, behavior)
726834
727819
  for (const [root3, { patternMap, getIg }] of matchersByRoot.entries()) {
726835
727820
  const ig = getIg();
726836
727821
  const relativePathStr = relativePath(root3 ?? getCwd(), fileAbsolutePath ?? getCwd());
726837
- if (relativePathStr.startsWith(`..${DIR_SEP}`)) {
727822
+ if (relativePathStr.startsWith(`..${DIR_SEP2}`)) {
726838
727823
  continue;
726839
727824
  }
726840
727825
  if (!relativePathStr) {
@@ -727295,7 +728280,7 @@ function checkReadableInternalPath(absolutePath, input2) {
727295
728280
  }
727296
728281
  return { behavior: "passthrough", message: "" };
727297
728282
  }
727298
- var import_ignore6, DANGEROUS_FILES2, DANGEROUS_DIRECTORIES2, DIR_SEP, getClaudeTempDir, getBundledSkillsRoot, getResolvedWorkingDirPaths, MATCHER_RECOMPILE_THRESHOLD = 1e4, MATCHER_CACHE_MAX_ENTRIES = 16, matcherCache;
728283
+ var import_ignore6, DANGEROUS_FILES2, DANGEROUS_DIRECTORIES2, DIR_SEP2, getClaudeTempDir, getBundledSkillsRoot, getResolvedWorkingDirPaths, MATCHER_RECOMPILE_THRESHOLD = 1e4, MATCHER_CACHE_MAX_ENTRIES = 16, matcherCache;
727299
728284
  var init_filesystem = __esm(() => {
727300
728285
  init_featureFlags();
727301
728286
  init_memoize();
@@ -727318,6 +728303,7 @@ var init_filesystem = __esm(() => {
727318
728303
  init_windowsPaths();
727319
728304
  init_PermissionUpdate();
727320
728305
  init_permissions2();
728306
+ init_symlinkEquivalences();
727321
728307
  import_ignore6 = __toESM(require_ignore(), 1);
727322
728308
  DANGEROUS_FILES2 = [
727323
728309
  ".gitconfig",
@@ -727338,7 +728324,7 @@ var init_filesystem = __esm(() => {
727338
728324
  ".claude",
727339
728325
  ".husky"
727340
728326
  ];
727341
- DIR_SEP = posix8.sep;
728327
+ DIR_SEP2 = posix9.sep;
727342
728328
  getClaudeTempDir = memoize_default(function getClaudeTempDir2() {
727343
728329
  const baseTmpDir = process.env.CLAUDE_CODE_TMPDIR || (getPlatform() === "windows" ? tmpdir15() : "/tmp");
727344
728330
  const fs26 = getFsImplementation();
@@ -762345,6 +763331,14 @@ var init_useBuddyNotification = __esm(() => {
762345
763331
  jsx_runtime402 = __toESM(require_jsx_runtime(), 1);
762346
763332
  });
762347
763333
 
763334
+ // src/hooks/historyEdited.ts
763335
+ function computeHistoryEdited(historyIndex, currentInput, recalledValue) {
763336
+ return historyIndex > 0 && currentInput !== recalledValue;
763337
+ }
763338
+ function computeSuppressSuggestions(isSearchingHistory, historyIndex, historyEdited) {
763339
+ return isSearchingHistory || historyIndex > 0 && !historyEdited;
763340
+ }
763341
+
762348
763342
  // src/hooks/useIdeConnectionStatus.ts
762349
763343
  function useIdeConnectionStatus(mcpClients) {
762350
763344
  return import_react223.useMemo(() => {
@@ -764062,6 +765056,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
764062
765056
  const historyCache = import_react235.useRef([]);
764063
765057
  const historyCacheModeFilter = import_react235.useRef(undefined);
764064
765058
  const historyIndexRef = import_react235.useRef(0);
765059
+ const recalledValueRef = import_react235.useRef(null);
764065
765060
  const initialModeFilterRef = import_react235.useRef(undefined);
764066
765061
  const currentInputRef = import_react235.useRef(currentInput);
764067
765062
  const pastedContentsRef = import_react235.useRef(pastedContents);
@@ -764070,6 +765065,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
764070
765065
  pastedContentsRef.current = pastedContents;
764071
765066
  currentModeRef.current = currentMode;
764072
765067
  const setInputWithCursor = import_react235.useCallback((value, mode, contents, cursorToStart = false) => {
765068
+ recalledValueRef.current = value;
764073
765069
  onSetInput(value, mode, contents);
764074
765070
  setCursorOffset?.(cursorToStart ? 0 : value.length);
764075
765071
  }, [onSetInput, setCursorOffset]);
@@ -764165,6 +765161,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
764165
765161
  setHistoryIndex(0);
764166
765162
  historyIndexRef.current = 0;
764167
765163
  initialModeFilterRef.current = undefined;
765164
+ recalledValueRef.current = null;
764168
765165
  removeNotification("search-history-hint");
764169
765166
  historyCache.current = [];
764170
765167
  historyCacheModeFilter.current = undefined;
@@ -764174,6 +765171,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
764174
765171
  }, [removeNotification]);
764175
765172
  return {
764176
765173
  historyIndex,
765174
+ historyEdited: computeHistoryEdited(historyIndex, currentInput, recalledValueRef.current),
764177
765175
  setHistoryIndex,
764178
765176
  onHistoryUp,
764179
765177
  onHistoryDown,
@@ -764181,7 +765179,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
764181
765179
  dismissSearchHint
764182
765180
  };
764183
765181
  }
764184
- var import_react235, jsx_runtime414, HISTORY_CHUNK_SIZE = 10, pendingLoad = null, pendingLoadTarget = 0, pendingLoadModeFilter = undefined;
765182
+ var import_react235, jsx_runtime414, HISTORY_CHUNK_SIZE = 10, pendingLoad = null, pendingLoadTarget = 0, pendingLoadModeFilter;
764185
765183
  var init_useArrowKeyHistory = __esm(() => {
764186
765184
  init_notifications();
764187
765185
  init_ConfigurableShortcutHint();
@@ -776184,7 +777182,8 @@ function PromptInput({
776184
777182
  onHistoryUp,
776185
777183
  onHistoryDown,
776186
777184
  dismissSearchHint,
776187
- historyIndex
777185
+ historyIndex,
777186
+ historyEdited
776188
777187
  } = useArrowKeyHistory((value, historyMode, pastedContents2) => {
776189
777188
  onChange(value);
776190
777189
  onModeChange(historyMode);
@@ -776335,7 +777334,7 @@ function PromptInput({
776335
777334
  agents: agents2,
776336
777335
  setSuggestionsState,
776337
777336
  suggestionsState,
776338
- suppressSuggestions: isSearchingHistory || historyIndex > 0,
777337
+ suppressSuggestions: computeSuppressSuggestions(isSearchingHistory, historyIndex, historyEdited),
776339
777338
  markAccepted,
776340
777339
  onModeChange
776341
777340
  });
@@ -797752,7 +798751,10 @@ function useMcpConnectivityStatus(t0) {
797752
798751
  }
797753
798752
  const failedLocalClients = mcpClients.filter(_temp225);
797754
798753
  const failedClaudeAiClients = mcpClients.filter(_temp286);
797755
- const needsAuthCount = getMcpNeedsAuthCount(mcpClients);
798754
+ if (countNoticedServersNowConnected(mcpClients) > 0) {
798755
+ pruneNoticedServersNowConnected(mcpClients);
798756
+ }
798757
+ const needsAuthCount = countNeedsAuthToAnnounce(mcpClients, MCP_NEEDS_AUTH_NOTICE_DEPS);
797756
798758
  if (failedLocalClients.length === 0 && failedClaudeAiClients.length === 0 && needsAuthCount === 0) {
797757
798759
  return;
797758
798760
  }
@@ -797829,6 +798831,7 @@ function useMcpConnectivityStatus(t0) {
797829
798831
  }),
797830
798832
  priority: "medium"
797831
798833
  });
798834
+ markNeedsAuthNoticed(mcpClients, MCP_NEEDS_AUTH_NOTICE_DEPS);
797832
798835
  }
797833
798836
  };
797834
798837
  t32 = [addNotification, mcpClients];
@@ -797848,16 +798851,21 @@ function _temp286(client_0) {
797848
798851
  function _temp225(client8) {
797849
798852
  return client8.type === "failed" && client8.config.type !== "sse-ide" && client8.config.type !== "ws-ide" && client8.config.type !== "claudeai-proxy";
797850
798853
  }
797851
- var import_compiler_runtime326, import_react303, jsx_runtime455, EMPTY_MCP_CLIENTS;
798854
+ var import_compiler_runtime326, import_react303, jsx_runtime455, EMPTY_MCP_CLIENTS, MCP_NEEDS_AUTH_NOTICE_DEPS;
797852
798855
  var init_useMcpConnectivityStatus = __esm(() => {
797853
798856
  init_notifications();
797854
798857
  init_state();
797855
798858
  init_ink2();
797856
798859
  init_claudeai();
798860
+ init_mcpNeedsAuthNotice();
797857
798861
  import_compiler_runtime326 = __toESM(require_compiler_runtime(), 1);
797858
798862
  import_react303 = __toESM(require_react(), 1);
797859
798863
  jsx_runtime455 = __toESM(require_jsx_runtime(), 1);
797860
798864
  EMPTY_MCP_CLIENTS = [];
798865
+ MCP_NEEDS_AUTH_NOTICE_DEPS = {
798866
+ hasEverConnected: hasClaudeAiMcpEverConnected,
798867
+ connectedThisSession: isClaudeAiMcpCurrentlyConnected
798868
+ };
797861
798869
  });
797862
798870
 
797863
798871
  // src/hooks/notifs/useAutoModeUnavailableNotification.ts
@@ -807091,13 +808099,13 @@ var init_bootstrap = __esm(() => {
807091
808099
  });
807092
808100
 
807093
808101
  // src/utils/warningHandler.ts
807094
- import { posix as posix9, win32 as win324 } from "path";
808102
+ import { posix as posix10, win32 as win324 } from "path";
807095
808103
  function isRunningFromBuildDirectory() {
807096
808104
  let invokedPath = process.argv[1] || "";
807097
808105
  let execPath2 = process.execPath || process.argv[0] || "";
807098
808106
  if (getPlatform() === "windows") {
807099
- invokedPath = invokedPath.split(win324.sep).join(posix9.sep);
807100
- execPath2 = execPath2.split(win324.sep).join(posix9.sep);
808107
+ invokedPath = invokedPath.split(win324.sep).join(posix10.sep);
808108
+ execPath2 = execPath2.split(win324.sep).join(posix10.sep);
807101
808109
  }
807102
808110
  const pathsToCheck = [invokedPath, execPath2];
807103
808111
  const buildDirs = [
@@ -823803,11 +824811,14 @@ async function mcpListHandler() {
823803
824811
  }), {
823804
824812
  concurrency: getMcpServerConnectionBatchSize()
823805
824813
  });
824814
+ const displayConfigs = getDisplayServers(configs, resolveUnexpandedMcpServers);
823806
824815
  for (const {
823807
824816
  name: name3,
823808
- server,
823809
824817
  status: status2
823810
824818
  } of results) {
824819
+ const server = displayConfigs[name3];
824820
+ if (!server)
824821
+ continue;
823811
824822
  if (server.type === "sse") {
823812
824823
  console.log(`${name3}: ${server.url} (SSE) - ${status2}`);
823813
824824
  } else if (server.type === "http") {
@@ -823834,12 +824845,13 @@ async function mcpGetHandler(name3) {
823834
824845
  console.log(` Scope: ${getScopeLabel(server.scope)}`);
823835
824846
  const status2 = await checkMcpServerHealth(name3, server);
823836
824847
  console.log(` Status: ${status2}`);
823837
- if (server.type === "sse") {
824848
+ const display = getDisplayConfig(name3, server, resolveUnexpandedMcpServers);
824849
+ if (display.type === "sse") {
823838
824850
  console.log(` Type: sse`);
823839
- console.log(` URL: ${server.url}`);
823840
- if (server.headers) {
824851
+ console.log(` URL: ${display.url}`);
824852
+ if (display.headers) {
823841
824853
  console.log(" Headers:");
823842
- for (const [key4, value] of Object.entries(server.headers)) {
824854
+ for (const [key4, value] of Object.entries(display.headers)) {
823843
824855
  console.log(` ${key4}: ${value}`);
823844
824856
  }
823845
824857
  }
@@ -823855,12 +824867,12 @@ async function mcpGetHandler(name3) {
823855
824867
  parts.push(`callback_port ${server.oauth.callbackPort}`);
823856
824868
  console.log(` OAuth: ${parts.join(", ")}`);
823857
824869
  }
823858
- } else if (server.type === "http") {
824870
+ } else if (display.type === "http") {
823859
824871
  console.log(` Type: http`);
823860
- console.log(` URL: ${server.url}`);
823861
- if (server.headers) {
824872
+ console.log(` URL: ${display.url}`);
824873
+ if (display.headers) {
823862
824874
  console.log(" Headers:");
823863
- for (const [key4, value] of Object.entries(server.headers)) {
824875
+ for (const [key4, value] of Object.entries(display.headers)) {
823864
824876
  console.log(` ${key4}: ${value}`);
823865
824877
  }
823866
824878
  }
@@ -823876,14 +824888,14 @@ async function mcpGetHandler(name3) {
823876
824888
  parts.push(`callback_port ${server.oauth.callbackPort}`);
823877
824889
  console.log(` OAuth: ${parts.join(", ")}`);
823878
824890
  }
823879
- } else if (server.type === "stdio") {
824891
+ } else if (display.type === "stdio") {
823880
824892
  console.log(` Type: stdio`);
823881
- console.log(` Command: ${server.command}`);
823882
- const args = Array.isArray(server.args) ? server.args : [];
824893
+ console.log(` Command: ${display.command}`);
824894
+ const args = Array.isArray(display.args) ? display.args : [];
823883
824895
  console.log(` Args: ${args.join(" ")}`);
823884
- if (server.env) {
824896
+ if (display.env) {
823885
824897
  console.log(" Environment:");
823886
- for (const [key4, value] of Object.entries(server.env)) {
824898
+ for (const [key4, value] of Object.entries(display.env)) {
823887
824899
  console.log(` ${key4}=${value}`);
823888
824900
  }
823889
824901
  }
@@ -824010,7 +825022,7 @@ After authorizing, paste the full redirect URL here and press Enter:`);
824010
825022
  });
824011
825023
  cliOk(`Successfully authenticated with MCP server "${name3}".`);
824012
825024
  } catch (error52) {
824013
- cliError(`Failed to authenticate with MCP server "${name3}": ${error52.message}`);
825025
+ cliError(`Failed to authenticate with MCP server "${name3}": ${redactMcpErrorDetail(name3, server, error52.message, resolveUnexpandedMcpServers)}`);
824014
825026
  }
824015
825027
  }
824016
825028
  async function mcpLogoutHandler(name3) {
@@ -824043,6 +825055,7 @@ var init_mcp5 = __esm(() => {
824043
825055
  init_auth11();
824044
825056
  init_client12();
824045
825057
  init_config6();
825058
+ init_redaction();
824046
825059
  init_utils9();
824047
825060
  init_normalization();
824048
825061
  init_AppState();
@@ -827596,6 +828609,7 @@ ${inputPrompt}` : mainThreadAgentDefinition.initialPrompt;
827596
828609
  effectiveMainLoopModel = ensureFableConsentSync(effectiveMainLoopModel);
827597
828610
  setInitialMainLoopModel(effectiveMainLoopModel);
827598
828611
  }
828612
+ emitStartupEffortCapWarning(parseEffortValue(options.effort) ?? getInitialEffortSetting(), parseUserSpecifiedModel(effectiveMainLoopModel ?? getDefaultMainLoopModel()), outputFormat);
827599
828613
  let advisorModel;
827600
828614
  if (isAdvisorEnabled()) {
827601
828615
  const advisorOption = canUserConfigureAdvisor() ? options.advisor : undefined;
@@ -829569,6 +830583,7 @@ var init_main7 = __esm(() => {
829569
830583
  init_autoCompactWindow();
829570
830584
  init_earlyInput();
829571
830585
  init_effort();
830586
+ init_cap();
829572
830587
  init_fastMode();
829573
830588
  init_managedEnv();
829574
830589
  init_messages3();