@cnwenf/occ 2.1.329 → 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 +948 -137
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
globalThis.MACRO={"VERSION":"2.1.
|
|
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;
|
|
@@ -203596,12 +203596,15 @@ function isPathInSandboxWriteAllowlist(resolvedPath) {
|
|
|
203596
203596
|
}
|
|
203597
203597
|
function isPathAllowed(resolvedPath, context4, operationType, precomputedPathsToCheck) {
|
|
203598
203598
|
const permissionType = operationType === "read" ? "read" : "edit";
|
|
203599
|
-
const
|
|
203600
|
-
|
|
203601
|
-
|
|
203602
|
-
|
|
203603
|
-
|
|
203604
|
-
|
|
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
|
+
}
|
|
203605
203608
|
}
|
|
203606
203609
|
if (operationType !== "read") {
|
|
203607
203610
|
const internalEditResult = checkEditableInternalPath(resolvedPath, {});
|
|
@@ -377483,43 +377486,40 @@ function getMaxBashTimeoutMs(env6 = process.env) {
|
|
|
377483
377486
|
var DEFAULT_TIMEOUT_MS = 120000, MAX_TIMEOUT_MS = 600000;
|
|
377484
377487
|
|
|
377485
377488
|
// src/utils/todoToolsAvailability.ts
|
|
377486
|
-
function isModelAtOrAboveRestrictedThreshold(modelId, restricted) {
|
|
377487
|
-
const match = /^claude-([a-z]+)-(\d+(?:-\d+)*)$/.exec(modelId);
|
|
377488
|
-
const family = match?.[1];
|
|
377489
|
-
const version5 = match?.[2];
|
|
377490
|
-
if (!family || !version5) {
|
|
377491
|
-
return false;
|
|
377492
|
-
}
|
|
377493
|
-
const threshold = restricted.find(([f4]) => f4 === family)?.[1];
|
|
377494
|
-
if (!threshold) {
|
|
377495
|
-
return false;
|
|
377496
|
-
}
|
|
377497
|
-
const segments = version5.split("-").map(Number);
|
|
377498
|
-
for (let i6 = 0;i6 < Math.max(segments.length, threshold.length); i6++) {
|
|
377499
|
-
const diff2 = (segments[i6] ?? 0) - (threshold[i6] ?? 0);
|
|
377500
|
-
if (diff2 !== 0) {
|
|
377501
|
-
return diff2 > 0;
|
|
377502
|
-
}
|
|
377503
|
-
}
|
|
377504
|
-
return true;
|
|
377505
|
-
}
|
|
377506
377489
|
function areTodoToolsAvailable() {
|
|
377507
377490
|
const model = getMainLoopModel();
|
|
377508
|
-
if (
|
|
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)) {
|
|
377509
377498
|
return true;
|
|
377510
377499
|
}
|
|
377511
377500
|
return isEnvTruthy(process.env.CLAUDE_CODE_ENABLE_TODO_TOOLS);
|
|
377512
377501
|
}
|
|
377513
|
-
var
|
|
377502
|
+
var TODO_TOOL_ALLOWED_MODELS;
|
|
377514
377503
|
var init_todoToolsAvailability = __esm(() => {
|
|
377515
377504
|
init_envUtils();
|
|
377516
377505
|
init_model();
|
|
377517
|
-
|
|
377518
|
-
|
|
377519
|
-
|
|
377520
|
-
|
|
377521
|
-
|
|
377522
|
-
|
|
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
|
+
]);
|
|
377523
377523
|
});
|
|
377524
377524
|
|
|
377525
377525
|
// src/utils/todo/types.ts
|
|
@@ -387726,6 +387726,518 @@ var init_common4 = __esm(() => {
|
|
|
387726
387726
|
trackedTabIds = new Set;
|
|
387727
387727
|
});
|
|
387728
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
|
+
|
|
387729
388241
|
// src/utils/plugins/mcpPluginIntegration.ts
|
|
387730
388242
|
import { join as join78 } from "path";
|
|
387731
388243
|
async function loadMcpServersFromMcpb(plugin, mcpbPath, errors8) {
|
|
@@ -387909,6 +388421,20 @@ function buildMcpUserConfig(plugin, serverName) {
|
|
|
387909
388421
|
return;
|
|
387910
388422
|
return { ...topLevel, ...channelSpecific };
|
|
387911
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
|
+
}
|
|
387912
388438
|
function resolvePluginMcpEnvironment(config6, plugin, userConfig, errors8, pluginName, serverName) {
|
|
387913
388439
|
const allMissingVars = [];
|
|
387914
388440
|
const resolveValue2 = (value) => {
|
|
@@ -387998,6 +388524,7 @@ async function getPluginMcpServers(plugin, errors8 = []) {
|
|
|
387998
388524
|
const userConfig = buildMcpUserConfig(plugin, name3);
|
|
387999
388525
|
try {
|
|
388000
388526
|
resolvedServers[name3] = resolvePluginMcpEnvironment(config6, plugin, userConfig, errors8, plugin.name, name3);
|
|
388527
|
+
registerAuthoredUnexpandedConfig(`plugin:${plugin.name}:${name3}`, buildAuthoredPluginConfig(config6, plugin));
|
|
388001
388528
|
} catch (err2) {
|
|
388002
388529
|
errors8?.push({
|
|
388003
388530
|
type: "generic-error",
|
|
@@ -388010,6 +388537,7 @@ async function getPluginMcpServers(plugin, errors8 = []) {
|
|
|
388010
388537
|
return addPluginScopeToServers(resolvedServers, plugin.name, plugin.source);
|
|
388011
388538
|
}
|
|
388012
388539
|
var init_mcpPluginIntegration = __esm(() => {
|
|
388540
|
+
init_redaction();
|
|
388013
388541
|
init_types();
|
|
388014
388542
|
init_debug();
|
|
388015
388543
|
init_errors();
|
|
@@ -388040,25 +388568,6 @@ function markClaudeAiMcpConnected(name3) {
|
|
|
388040
388568
|
function isClaudeAiMcpCurrentlyConnected(name3) {
|
|
388041
388569
|
return currentlyConnectedClaudeAiMcps.has(name3);
|
|
388042
388570
|
}
|
|
388043
|
-
function shouldCountClaudeAiNeedsAuth(client8) {
|
|
388044
|
-
if (client8.config.type !== "claudeai-proxy")
|
|
388045
|
-
return false;
|
|
388046
|
-
const eligible2 = client8.config.eligible;
|
|
388047
|
-
if (eligible2 === false && !isClaudeAiMcpCurrentlyConnected(client8.name)) {
|
|
388048
|
-
return false;
|
|
388049
|
-
}
|
|
388050
|
-
return hasClaudeAiMcpEverConnected(client8.name);
|
|
388051
|
-
}
|
|
388052
|
-
function getMcpNeedsAuthCount(clients) {
|
|
388053
|
-
return clients.filter((client8) => {
|
|
388054
|
-
if (client8.type !== "needs-auth")
|
|
388055
|
-
return false;
|
|
388056
|
-
if (client8.config.type === "claudeai-proxy") {
|
|
388057
|
-
return shouldCountClaudeAiNeedsAuth(client8);
|
|
388058
|
-
}
|
|
388059
|
-
return client8.config.type !== "sse-ide" && client8.config.type !== "ws-ide";
|
|
388060
|
-
}).length;
|
|
388061
|
-
}
|
|
388062
388571
|
var FETCH_TIMEOUT_MS = 5000, MCP_SERVERS_BETA_HEADER = "mcp-servers-2025-12-04", fetchClaudeAIMcpConfigsIfEligible, currentlyConnectedClaudeAiMcps;
|
|
388063
388572
|
var init_claudeai = __esm(() => {
|
|
388064
388573
|
init_axios2();
|
|
@@ -388323,18 +388832,22 @@ function mcpServerHealthStatusLabel(result) {
|
|
|
388323
388832
|
function isUnconfiguredMcpServer(result) {
|
|
388324
388833
|
return result.type === "failed" && result.errorCode === "UNCONFIGURED";
|
|
388325
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
|
+
}
|
|
388326
388839
|
function getMcpServerFailureMessage(result) {
|
|
388840
|
+
const endpoint3 = getMcpErrorEndpoint(result.name, result.config, { detail: "origin" }, resolveUnexpandedMcpServers);
|
|
388327
388841
|
const errorCode = result.errorCode;
|
|
388328
|
-
|
|
388329
|
-
|
|
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;
|
|
388330
388845
|
}
|
|
388331
388846
|
if (errorCode) {
|
|
388332
|
-
const
|
|
388333
|
-
|
|
388334
|
-
const url3 = "url" in result.config && typeof result.config.url === "string" ? result.config.url : null;
|
|
388335
|
-
return url3 ? `${message} at ${url3}` : message;
|
|
388847
|
+
const message = formatErrorCode(errorCode);
|
|
388848
|
+
return endpoint3 ? `${message} at ${endpoint3}` : message;
|
|
388336
388849
|
}
|
|
388337
|
-
return result.error
|
|
388850
|
+
return result.error !== undefined ? redact(result.error) : "";
|
|
388338
388851
|
}
|
|
388339
388852
|
function getMcpServerScopeFromToolName(toolName) {
|
|
388340
388853
|
if (!isMcpTool({ name: toolName })) {
|
|
@@ -388437,7 +388950,15 @@ function getLoggingSafeMcpBaseUrl(config6) {
|
|
|
388437
388950
|
return;
|
|
388438
388951
|
}
|
|
388439
388952
|
}
|
|
388440
|
-
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
|
+
};
|
|
388441
388962
|
var init_utils9 = __esm(() => {
|
|
388442
388963
|
init_state();
|
|
388443
388964
|
init_cwd2();
|
|
@@ -388447,6 +388968,7 @@ var init_utils9 = __esm(() => {
|
|
|
388447
388968
|
init_slowOperations();
|
|
388448
388969
|
init_config6();
|
|
388449
388970
|
init_mcpStringUtils();
|
|
388971
|
+
init_redaction();
|
|
388450
388972
|
init_normalization();
|
|
388451
388973
|
init_types();
|
|
388452
388974
|
NAMED_FAILURE_ERROR_CODES = new Set([
|
|
@@ -388522,7 +389044,7 @@ function commandArraysMatch(a5, b5) {
|
|
|
388522
389044
|
}
|
|
388523
389045
|
return a5.every((val, idx) => val === b5[idx]);
|
|
388524
389046
|
}
|
|
388525
|
-
function
|
|
389047
|
+
function getServerUrl2(config6) {
|
|
388526
389048
|
return "url" in config6 ? config6.url : null;
|
|
388527
389049
|
}
|
|
388528
389050
|
function unwrapCcrProxyUrl(url3) {
|
|
@@ -388542,7 +389064,7 @@ function getMcpServerSignature(config6) {
|
|
|
388542
389064
|
if (cmd) {
|
|
388543
389065
|
return `stdio:${jsonStringify(cmd)}`;
|
|
388544
389066
|
}
|
|
388545
|
-
const url3 =
|
|
389067
|
+
const url3 = getServerUrl2(config6);
|
|
388546
389068
|
if (url3) {
|
|
388547
389069
|
return `url:${unwrapCcrProxyUrl(url3)}`;
|
|
388548
389070
|
}
|
|
@@ -388641,7 +389163,7 @@ function isMcpServerDenied(serverName, config6) {
|
|
|
388641
389163
|
}
|
|
388642
389164
|
}
|
|
388643
389165
|
}
|
|
388644
|
-
const serverUrl =
|
|
389166
|
+
const serverUrl = getServerUrl2(config6);
|
|
388645
389167
|
if (serverUrl) {
|
|
388646
389168
|
for (const entry of settings.deniedMcpServers) {
|
|
388647
389169
|
if (isMcpServerUrlEntry(entry) && urlMatchesPattern(serverUrl, entry.serverUrl)) {
|
|
@@ -388667,7 +389189,7 @@ function isMcpServerAllowedByPolicy(serverName, config6) {
|
|
|
388667
389189
|
const hasUrlEntries = settings.allowedMcpServers.some(isMcpServerUrlEntry);
|
|
388668
389190
|
if (config6) {
|
|
388669
389191
|
const serverCommand = getServerCommandArray(config6);
|
|
388670
|
-
const serverUrl =
|
|
389192
|
+
const serverUrl = getServerUrl2(config6);
|
|
388671
389193
|
if (serverCommand) {
|
|
388672
389194
|
if (hasCommandEntries) {
|
|
388673
389195
|
for (const entry of settings.allowedMcpServers) {
|
|
@@ -388964,7 +389486,7 @@ function getProjectMcpConfigsFromCwd() {
|
|
|
388964
389486
|
errors: errors8 || []
|
|
388965
389487
|
};
|
|
388966
389488
|
}
|
|
388967
|
-
function getMcpConfigsByScope(scope) {
|
|
389489
|
+
function getMcpConfigsByScope(scope, options) {
|
|
388968
389490
|
const sourceMap = {
|
|
388969
389491
|
project: "projectSettings",
|
|
388970
389492
|
user: "userSettings",
|
|
@@ -388987,7 +389509,7 @@ function getMcpConfigsByScope(scope) {
|
|
|
388987
389509
|
const mcpJsonPath = join80(dir, ".mcp.json");
|
|
388988
389510
|
const { config: config6, errors: errors8 } = parseMcpConfigFromFilePath({
|
|
388989
389511
|
filePath: mcpJsonPath,
|
|
388990
|
-
expandVars: true,
|
|
389512
|
+
expandVars: options?.expandVars ?? true,
|
|
388991
389513
|
scope: "project"
|
|
388992
389514
|
});
|
|
388993
389515
|
if (!config6) {
|
|
@@ -389017,7 +389539,7 @@ function getMcpConfigsByScope(scope) {
|
|
|
389017
389539
|
}
|
|
389018
389540
|
const { config: config6, errors: errors8 } = parseMcpConfig({
|
|
389019
389541
|
configObject: { mcpServers },
|
|
389020
|
-
expandVars: true,
|
|
389542
|
+
expandVars: options?.expandVars ?? true,
|
|
389021
389543
|
scope: "user"
|
|
389022
389544
|
});
|
|
389023
389545
|
return {
|
|
@@ -389032,7 +389554,7 @@ function getMcpConfigsByScope(scope) {
|
|
|
389032
389554
|
}
|
|
389033
389555
|
const { config: config6, errors: errors8 } = parseMcpConfig({
|
|
389034
389556
|
configObject: { mcpServers },
|
|
389035
|
-
expandVars: true,
|
|
389557
|
+
expandVars: options?.expandVars ?? true,
|
|
389036
389558
|
scope: "local"
|
|
389037
389559
|
});
|
|
389038
389560
|
return {
|
|
@@ -389044,7 +389566,7 @@ function getMcpConfigsByScope(scope) {
|
|
|
389044
389566
|
const enterpriseMcpPath = getEnterpriseMcpFilePath();
|
|
389045
389567
|
const { config: config6, errors: errors8 } = parseMcpConfigFromFilePath({
|
|
389046
389568
|
filePath: enterpriseMcpPath,
|
|
389047
|
-
expandVars: true,
|
|
389569
|
+
expandVars: options?.expandVars ?? true,
|
|
389048
389570
|
scope: "enterprise"
|
|
389049
389571
|
});
|
|
389050
389572
|
if (!config6) {
|
|
@@ -389432,6 +389954,10 @@ function parseDynamicMcpConfig(params) {
|
|
|
389432
389954
|
}
|
|
389433
389955
|
let serverConfig = validated;
|
|
389434
389956
|
if (expandVars) {
|
|
389957
|
+
registerAuthoredUnexpandedConfig(name3, {
|
|
389958
|
+
...validated,
|
|
389959
|
+
scope
|
|
389960
|
+
});
|
|
389435
389961
|
const { expanded, missingVars, urlExpandedToEmpty } = expandEnvVars(validated);
|
|
389436
389962
|
if (missingVars.length > 0) {
|
|
389437
389963
|
pushEntryError(name3, `Missing environment variables: ${missingVars.join(", ")}`, `Set the following environment variables: ${missingVars.join(", ")}`, undefined);
|
|
@@ -389537,6 +390063,7 @@ var init_config6 = __esm(() => {
|
|
|
389537
390063
|
init_slowOperations();
|
|
389538
390064
|
init_analytics();
|
|
389539
390065
|
init_claudeai();
|
|
390066
|
+
init_redaction();
|
|
389540
390067
|
init_types();
|
|
389541
390068
|
init_utils9();
|
|
389542
390069
|
init_normalization();
|
|
@@ -439044,7 +439571,8 @@ async function authStatus(opts) {
|
|
|
439044
439571
|
const output = {
|
|
439045
439572
|
loggedIn,
|
|
439046
439573
|
authMethod,
|
|
439047
|
-
apiProvider
|
|
439574
|
+
apiProvider,
|
|
439575
|
+
configDirectory: getClaudeConfigHomeDir()
|
|
439048
439576
|
};
|
|
439049
439577
|
if (resolvedApiKeySource) {
|
|
439050
439578
|
output.apiKeySource = resolvedApiKeySource;
|
|
@@ -453078,6 +453606,15 @@ function parseRGB(colorStr) {
|
|
|
453078
453606
|
RGB_CACHE.set(colorStr, result);
|
|
453079
453607
|
return result;
|
|
453080
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
|
+
}
|
|
453081
453618
|
var THINKING_AMBER_DELAY_MS = 1e4, THINKING_AMBER_RAMP_MS = 1e4, RGB_CACHE;
|
|
453082
453619
|
var init_utils10 = __esm(() => {
|
|
453083
453620
|
RGB_CACHE = new Map;
|
|
@@ -459880,7 +460417,8 @@ function SpinnerWithVerbInner({
|
|
|
459880
460417
|
const currentTodo = tasksV2?.find((task) => task.status !== "pending" && task.status !== "completed");
|
|
459881
460418
|
const nextTask = findNextPendingTask(tasksV2);
|
|
459882
460419
|
const [randomVerb] = import_react64.useState(() => sample_default(getSpinnerVerbs()));
|
|
459883
|
-
const
|
|
460420
|
+
const leaderTodoLabel = currentTodo ? computeTodoLabel(currentTodo) : undefined;
|
|
460421
|
+
const leaderVerb = overrideMessage ?? (leaderTodoLabel === undefined ? undefined : truncateToWidthNoEllipsis(leaderTodoLabel, computeSpinnerVerbWidth(columns))) ?? randomVerb;
|
|
459884
460422
|
const effectiveVerb = foregroundedTeammate && !foregroundedTeammate.isIdle ? foregroundedTeammate.spinnerVerb ?? randomVerb : leaderVerb;
|
|
459885
460423
|
const message = effectiveVerb + "\u2026";
|
|
459886
460424
|
import_react64.useEffect(() => {
|
|
@@ -460052,7 +460590,8 @@ function SpinnerWithVerbInner({
|
|
|
460052
460590
|
(nextTask || effectiveTip) && /* @__PURE__ */ jsx_runtime82.jsx(MessageResponse, {
|
|
460053
460591
|
children: /* @__PURE__ */ jsx_runtime82.jsx(ThemedText, {
|
|
460054
460592
|
dimColor: true,
|
|
460055
|
-
|
|
460593
|
+
wrap: nextTask ? "truncate-end" : "wrap",
|
|
460594
|
+
children: nextTask ? `Next: ${collapseWhitespace(nextTask.subject)}` : `Tip: ${effectiveTip}`
|
|
460056
460595
|
})
|
|
460057
460596
|
})
|
|
460058
460597
|
]
|
|
@@ -460402,6 +460941,7 @@ var init_Spinner2 = __esm(() => {
|
|
|
460402
460941
|
init_useTerminalSize();
|
|
460403
460942
|
init_stringWidth();
|
|
460404
460943
|
init_Spinner();
|
|
460944
|
+
init_utils10();
|
|
460405
460945
|
init_SpinnerAnimationRow();
|
|
460406
460946
|
init_useSettings();
|
|
460407
460947
|
init_InProcessTeammateTask();
|
|
@@ -497292,7 +497832,7 @@ function filterValue(rule, node, options) {
|
|
|
497292
497832
|
throw new TypeError("`filter` needs to be a string, array, or function");
|
|
497293
497833
|
}
|
|
497294
497834
|
}
|
|
497295
|
-
function
|
|
497835
|
+
function collapseWhitespace2(options) {
|
|
497296
497836
|
var element = options.element;
|
|
497297
497837
|
var isBlock2 = options.isBlock;
|
|
497298
497838
|
var isVoid2 = options.isVoid;
|
|
@@ -497384,7 +497924,7 @@ function RootNode(input, options) {
|
|
|
497384
497924
|
} else {
|
|
497385
497925
|
root3 = input.cloneNode(true);
|
|
497386
497926
|
}
|
|
497387
|
-
|
|
497927
|
+
collapseWhitespace2({
|
|
497388
497928
|
element: root3,
|
|
497389
497929
|
isBlock,
|
|
497390
497930
|
isVoid,
|
|
@@ -497957,6 +498497,7 @@ __export(exports_utils2, {
|
|
|
497957
498497
|
validateURL: () => validateURL,
|
|
497958
498498
|
isPreapprovedUrl: () => isPreapprovedUrl,
|
|
497959
498499
|
isPermittedRedirect: () => isPermittedRedirect,
|
|
498500
|
+
invalidUrlErrorMessage: () => invalidUrlErrorMessage,
|
|
497960
498501
|
getWithPermittedRedirects: () => getWithPermittedRedirects,
|
|
497961
498502
|
getURLMarkdownContent: () => getURLMarkdownContent,
|
|
497962
498503
|
getTurndownService: () => getTurndownService,
|
|
@@ -498010,6 +498551,18 @@ function validateURL(url3) {
|
|
|
498010
498551
|
}
|
|
498011
498552
|
return true;
|
|
498012
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
|
+
}
|
|
498013
498566
|
async function checkDomainBlocklist(domain2) {
|
|
498014
498567
|
if (DOMAIN_CHECK_CACHE.has(domain2)) {
|
|
498015
498568
|
return { status: "allowed" };
|
|
@@ -498099,7 +498652,7 @@ function isRedirectInfo(response3) {
|
|
|
498099
498652
|
}
|
|
498100
498653
|
async function getURLMarkdownContent(url3, abortController) {
|
|
498101
498654
|
if (!validateURL(url3)) {
|
|
498102
|
-
throw new Error(
|
|
498655
|
+
throw new Error(invalidUrlErrorMessage(url3));
|
|
498103
498656
|
}
|
|
498104
498657
|
const cachedEntry = URL_CACHE.get(url3);
|
|
498105
498658
|
if (cachedEntry) {
|
|
@@ -605131,12 +605684,8 @@ ${customInstructions}`;
|
|
|
605131
605684
|
function formatCompactSummary(summary) {
|
|
605132
605685
|
let formattedSummary = summary;
|
|
605133
605686
|
formattedSummary = formattedSummary.replace(/<analysis>[\s\S]*?<\/analysis>/, "");
|
|
605134
|
-
|
|
605135
|
-
|
|
605136
|
-
const content = summaryMatch[1] || "";
|
|
605137
|
-
formattedSummary = formattedSummary.replace(/<summary>[\s\S]*?<\/summary>/, `Summary:
|
|
605138
|
-
${content.trim()}`);
|
|
605139
|
-
}
|
|
605687
|
+
formattedSummary = formattedSummary.replace(/<summary>([\s\S]*?)<\/summary>/, (_m4, g5) => `Summary:
|
|
605688
|
+
${(g5 ?? "").trim()}`);
|
|
605140
605689
|
formattedSummary = formattedSummary.replace(/\n\n+/g, `
|
|
605141
605690
|
|
|
605142
605691
|
`);
|
|
@@ -614927,7 +615476,7 @@ function isClassifierDenial(content) {
|
|
|
614927
615476
|
function buildYoloRejectionMessage(reason) {
|
|
614928
615477
|
const prefix = AUTO_MODE_REJECTION_PREFIX;
|
|
614929
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.`;
|
|
614930
|
-
return `${prefix}${reason}. ` + `If you have other tasks that don't depend on this action, continue working on those. ` + `${
|
|
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;
|
|
614931
615480
|
}
|
|
614932
615481
|
function buildClassifierUnavailableMessage(toolName, classifierModel) {
|
|
614933
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.`;
|
|
@@ -618328,7 +618877,7 @@ Note: The user's next message may contain a correction or preference. Pay close
|
|
|
618328
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.
|
|
618329
618878
|
|
|
618330
618879
|
Rejected plan:
|
|
618331
|
-
`, 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
|
|
618332
618881
|
Goal: Write your final plan to the plan file (the only file you can edit).
|
|
618333
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
|
|
618334
618883
|
- Include only your recommended approach, not all alternatives
|
|
@@ -618403,7 +618952,10 @@ var init_messages3 = __esm(() => {
|
|
|
618403
618952
|
init_stringUtils();
|
|
618404
618953
|
init_tasks();
|
|
618405
618954
|
init_toolSearch();
|
|
618406
|
-
|
|
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}`;
|
|
618407
618959
|
SYNTHETIC_MESSAGES = new Set([
|
|
618408
618960
|
INTERRUPT_MESSAGE,
|
|
618409
618961
|
INTERRUPT_MESSAGE_FOR_TOOL_USE,
|
|
@@ -646389,6 +646941,86 @@ var init_magicDocs = __esm(() => {
|
|
|
646389
646941
|
});
|
|
646390
646942
|
});
|
|
646391
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
|
+
|
|
646392
647024
|
// src/commands/clear/caches.ts
|
|
646393
647025
|
var exports_caches = {};
|
|
646394
647026
|
__export(exports_caches, {
|
|
@@ -646411,6 +647043,7 @@ function clearSessionCaches(preservedAgentIds = new Set) {
|
|
|
646411
647043
|
resetGetMemoryFilesCache("session_start");
|
|
646412
647044
|
clearStoredImagePaths();
|
|
646413
647045
|
clearAllSessions();
|
|
647046
|
+
clearNeedsAuthNoticedThisSession();
|
|
646414
647047
|
if (!hasPreserved)
|
|
646415
647048
|
clearAllPendingCallbacks();
|
|
646416
647049
|
if (process.env.USER_TYPE === "ant") {
|
|
@@ -646458,6 +647091,7 @@ var init_caches = __esm(() => {
|
|
|
646458
647091
|
init_detectRepository();
|
|
646459
647092
|
init_gitFilesystem();
|
|
646460
647093
|
init_imageStore();
|
|
647094
|
+
init_mcpNeedsAuthNotice();
|
|
646461
647095
|
init_sessionEnvVars();
|
|
646462
647096
|
});
|
|
646463
647097
|
|
|
@@ -668772,6 +669406,12 @@ function MCPRemoteServerMenu({
|
|
|
668772
669406
|
} = useTerminalSize();
|
|
668773
669407
|
const [isAuthenticating, setIsAuthenticating] = import_react131.default.useState(false);
|
|
668774
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 : "";
|
|
668775
669415
|
const mcp = useAppState((s4) => s4.mcp);
|
|
668776
669416
|
const setAppState = useSetAppState();
|
|
668777
669417
|
const [authorizationUrl, setAuthorizationUrl] = import_react131.default.useState(null);
|
|
@@ -668984,7 +669624,7 @@ function MCPRemoteServerMenu({
|
|
|
668984
669624
|
}
|
|
668985
669625
|
} catch (err_1) {
|
|
668986
669626
|
if (err_1 instanceof Error && !(err_1 instanceof AuthenticationCancelledError)) {
|
|
668987
|
-
setError(err_1.message);
|
|
669627
|
+
setError(redactMcpErrorDetail(server.name, scopedConfig, err_1.message, resolveUnexpandedMcpServers));
|
|
668988
669628
|
}
|
|
668989
669629
|
} finally {
|
|
668990
669630
|
setIsAuthenticating(false);
|
|
@@ -669502,7 +670142,7 @@ function MCPRemoteServerMenu({
|
|
|
669502
670142
|
}),
|
|
669503
670143
|
/* @__PURE__ */ jsx_runtime238.jsx(ThemedText, {
|
|
669504
670144
|
dimColor: true,
|
|
669505
|
-
children:
|
|
670145
|
+
children: displayUrl
|
|
669506
670146
|
})
|
|
669507
670147
|
]
|
|
669508
670148
|
}),
|
|
@@ -669656,6 +670296,7 @@ var init_MCPRemoteServerMenu = __esm(() => {
|
|
|
669656
670296
|
init_auth11();
|
|
669657
670297
|
init_client12();
|
|
669658
670298
|
init_MCPConnectionManager();
|
|
670299
|
+
init_redaction();
|
|
669659
670300
|
init_utils9();
|
|
669660
670301
|
init_AppState();
|
|
669661
670302
|
init_auth6();
|
|
@@ -669689,6 +670330,12 @@ function MCPStdioServerMenu({
|
|
|
669689
670330
|
const reconnectMcpServer = useMcpReconnect();
|
|
669690
670331
|
const toggleMcpServer = useMcpToggleEnabled();
|
|
669691
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 : [];
|
|
669692
670339
|
const handleToggleEnabled = import_react132.default.useCallback(async () => {
|
|
669693
670340
|
const wasEnabled = server.client.type !== "disabled";
|
|
669694
670341
|
try {
|
|
@@ -669824,11 +670471,11 @@ function MCPStdioServerMenu({
|
|
|
669824
670471
|
}),
|
|
669825
670472
|
/* @__PURE__ */ jsx_runtime239.jsx(ThemedText, {
|
|
669826
670473
|
dimColor: true,
|
|
669827
|
-
children:
|
|
670474
|
+
children: displayCommand
|
|
669828
670475
|
})
|
|
669829
670476
|
]
|
|
669830
670477
|
}),
|
|
669831
|
-
|
|
670478
|
+
displayArgs.length > 0 && /* @__PURE__ */ jsx_runtime239.jsxs(ThemedBox_default, {
|
|
669832
670479
|
children: [
|
|
669833
670480
|
/* @__PURE__ */ jsx_runtime239.jsx(ThemedText, {
|
|
669834
670481
|
bold: true,
|
|
@@ -669836,7 +670483,7 @@ function MCPStdioServerMenu({
|
|
|
669836
670483
|
}),
|
|
669837
670484
|
/* @__PURE__ */ jsx_runtime239.jsx(ThemedText, {
|
|
669838
670485
|
dimColor: true,
|
|
669839
|
-
children:
|
|
670486
|
+
children: displayArgs.join(" ")
|
|
669840
670487
|
})
|
|
669841
670488
|
]
|
|
669842
670489
|
}),
|
|
@@ -669946,6 +670593,7 @@ var init_MCPStdioServerMenu = __esm(() => {
|
|
|
669946
670593
|
init_ink2();
|
|
669947
670594
|
init_config6();
|
|
669948
670595
|
init_MCPConnectionManager();
|
|
670596
|
+
init_redaction();
|
|
669949
670597
|
init_utils9();
|
|
669950
670598
|
init_AppState();
|
|
669951
670599
|
init_errors();
|
|
@@ -679149,7 +679797,7 @@ function formatZodErrors(zodError) {
|
|
|
679149
679797
|
}));
|
|
679150
679798
|
}
|
|
679151
679799
|
function checkPathTraversal(p4, field, errors8, hint) {
|
|
679152
|
-
if (p4.
|
|
679800
|
+
if (p4.split(/[\\/]/).some((segment2) => segment2 === "..")) {
|
|
679153
679801
|
errors8.push({
|
|
679154
679802
|
path: field,
|
|
679155
679803
|
message: hint ? `Path contains "..": ${p4}. ${hint}` : `Path contains ".." which could be a path traversal attempt: ${p4}`
|
|
@@ -726154,7 +726802,15 @@ function stripNonLoadedContent(raw) {
|
|
|
726154
726802
|
}
|
|
726155
726803
|
return result;
|
|
726156
726804
|
}
|
|
726157
|
-
function
|
|
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") {
|
|
726158
726814
|
const trimmed = raw.trim();
|
|
726159
726815
|
const contentLines = trimmed.split(`
|
|
726160
726816
|
`);
|
|
@@ -726178,11 +726834,20 @@ function truncateEntrypointContent(raw) {
|
|
|
726178
726834
|
`, MAX_ENTRYPOINT_BYTES);
|
|
726179
726835
|
truncated = truncated.slice(0, cutAt > 0 ? cutAt : MAX_ENTRYPOINT_BYTES);
|
|
726180
726836
|
}
|
|
726181
|
-
const
|
|
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.`;
|
|
726182
726847
|
return {
|
|
726183
726848
|
content: truncated + `
|
|
726184
726849
|
|
|
726185
|
-
> WARNING: ${
|
|
726850
|
+
> WARNING: ${warning}`,
|
|
726186
726851
|
lineCount,
|
|
726187
726852
|
byteCount,
|
|
726188
726853
|
wasLineTruncated,
|
|
@@ -726499,7 +727164,7 @@ async function loadMemoryPrompt() {
|
|
|
726499
727164
|
}
|
|
726500
727165
|
return null;
|
|
726501
727166
|
}
|
|
726502
|
-
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).";
|
|
726503
727168
|
var init_memdir = __esm(() => {
|
|
726504
727169
|
init_featureFlags();
|
|
726505
727170
|
init_marked_esm();
|
|
@@ -726517,6 +727182,8 @@ var init_memdir = __esm(() => {
|
|
|
726517
727182
|
init_format();
|
|
726518
727183
|
init_sessionStorage();
|
|
726519
727184
|
init_settings2();
|
|
727185
|
+
init_stringUtils();
|
|
727186
|
+
init_truncateMiddle();
|
|
726520
727187
|
init_memoryTypes();
|
|
726521
727188
|
teamMemPaths7 = feature("TEAMMEM") ? (init_teamMemPaths(), __toCommonJS(exports_teamMemPaths)) : null;
|
|
726522
727189
|
HTML_COMMENT_REGEX = /<!--[\s\S]*?-->/g;
|
|
@@ -726595,10 +727262,108 @@ var init_agentMemory = __esm(() => {
|
|
|
726595
727262
|
init_path2();
|
|
726596
727263
|
});
|
|
726597
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
|
+
|
|
726598
727363
|
// src/utils/permissions/filesystem.ts
|
|
726599
727364
|
import { randomBytes as randomBytes19 } from "crypto";
|
|
726600
727365
|
import { homedir as homedir44, tmpdir as tmpdir15 } from "os";
|
|
726601
|
-
import { join as join164, normalize as normalize18, posix as
|
|
727366
|
+
import { join as join164, normalize as normalize18, posix as posix9, sep as sep47 } from "path";
|
|
726602
727367
|
function normalizeCaseForComparison2(path39) {
|
|
726603
727368
|
return path39.toLowerCase();
|
|
726604
727369
|
}
|
|
@@ -726641,9 +727406,9 @@ function relativePath(from2, to) {
|
|
|
726641
727406
|
if (getPlatform() === "windows") {
|
|
726642
727407
|
const posixFrom = windowsPathToPosixPath(from2);
|
|
726643
727408
|
const posixTo = windowsPathToPosixPath(to);
|
|
726644
|
-
return
|
|
727409
|
+
return posix9.relative(posixFrom, posixTo);
|
|
726645
727410
|
}
|
|
726646
|
-
return
|
|
727411
|
+
return posix9.relative(from2, to);
|
|
726647
727412
|
}
|
|
726648
727413
|
function toPosixPath(path39) {
|
|
726649
727414
|
if (getPlatform() === "windows") {
|
|
@@ -726838,7 +727603,7 @@ function pathInWorkingPath(path39, workingPath) {
|
|
|
726838
727603
|
if (containsPathTraversal(relative32)) {
|
|
726839
727604
|
return false;
|
|
726840
727605
|
}
|
|
726841
|
-
return !
|
|
727606
|
+
return !posix9.isAbsolute(relative32);
|
|
726842
727607
|
}
|
|
726843
727608
|
function rootPathForSource(source2) {
|
|
726844
727609
|
switch (source2) {
|
|
@@ -726855,25 +727620,25 @@ function rootPathForSource(source2) {
|
|
|
726855
727620
|
}
|
|
726856
727621
|
}
|
|
726857
727622
|
function prependDirSep(path39) {
|
|
726858
|
-
return
|
|
727623
|
+
return posix9.join(DIR_SEP2, path39);
|
|
726859
727624
|
}
|
|
726860
727625
|
function normalizePatternToPath({
|
|
726861
727626
|
patternRoot,
|
|
726862
727627
|
pattern,
|
|
726863
727628
|
rootPath
|
|
726864
727629
|
}) {
|
|
726865
|
-
const fullPattern =
|
|
727630
|
+
const fullPattern = posix9.join(patternRoot, pattern);
|
|
726866
727631
|
if (patternRoot === rootPath) {
|
|
726867
727632
|
return prependDirSep(pattern);
|
|
726868
|
-
} else if (fullPattern.startsWith(`${rootPath}${
|
|
727633
|
+
} else if (fullPattern.startsWith(`${rootPath}${DIR_SEP2}`)) {
|
|
726869
727634
|
const relativePart = fullPattern.slice(rootPath.length);
|
|
726870
727635
|
return prependDirSep(relativePart);
|
|
726871
727636
|
} else {
|
|
726872
|
-
const relativePath2 =
|
|
726873
|
-
if (!relativePath2 || relativePath2.startsWith(`..${
|
|
727637
|
+
const relativePath2 = posix9.relative(rootPath, patternRoot);
|
|
727638
|
+
if (!relativePath2 || relativePath2.startsWith(`..${DIR_SEP2}`) || relativePath2 === "..") {
|
|
726874
727639
|
return null;
|
|
726875
727640
|
} else {
|
|
726876
|
-
const relativePattern =
|
|
727641
|
+
const relativePattern = posix9.join(relativePath2, pattern);
|
|
726877
727642
|
return prependDirSep(relativePattern);
|
|
726878
727643
|
}
|
|
726879
727644
|
}
|
|
@@ -726906,7 +727671,7 @@ function getFileReadIgnorePatterns(toolPermissionContext) {
|
|
|
726906
727671
|
return result;
|
|
726907
727672
|
}
|
|
726908
727673
|
function patternWithRoot(pattern, source2) {
|
|
726909
|
-
if (pattern.startsWith(`${
|
|
727674
|
+
if (pattern.startsWith(`${DIR_SEP2}${DIR_SEP2}`)) {
|
|
726910
727675
|
const patternWithoutDoubleSlash = pattern.slice(1);
|
|
726911
727676
|
if (getPlatform() === "windows" && patternWithoutDoubleSlash.match(/^\/[a-z]\//i)) {
|
|
726912
727677
|
const driveLetter = patternWithoutDoubleSlash[1]?.toUpperCase() ?? "C";
|
|
@@ -726920,21 +727685,21 @@ function patternWithRoot(pattern, source2) {
|
|
|
726920
727685
|
}
|
|
726921
727686
|
return {
|
|
726922
727687
|
relativePattern: patternWithoutDoubleSlash,
|
|
726923
|
-
root:
|
|
727688
|
+
root: DIR_SEP2
|
|
726924
727689
|
};
|
|
726925
|
-
} else if (pattern.startsWith(`~${
|
|
727690
|
+
} else if (pattern.startsWith(`~${DIR_SEP2}`)) {
|
|
726926
727691
|
return {
|
|
726927
727692
|
relativePattern: pattern.slice(1),
|
|
726928
727693
|
root: homedir44().normalize("NFC")
|
|
726929
727694
|
};
|
|
726930
|
-
} else if (pattern.startsWith(
|
|
727695
|
+
} else if (pattern.startsWith(DIR_SEP2)) {
|
|
726931
727696
|
return {
|
|
726932
727697
|
relativePattern: pattern,
|
|
726933
727698
|
root: rootPathForSource(source2)
|
|
726934
727699
|
};
|
|
726935
727700
|
}
|
|
726936
727701
|
let normalizedPattern = pattern;
|
|
726937
|
-
if (pattern.startsWith(`.${
|
|
727702
|
+
if (pattern.startsWith(`.${DIR_SEP2}`)) {
|
|
726938
727703
|
normalizedPattern = pattern.slice(2);
|
|
726939
727704
|
}
|
|
726940
727705
|
return {
|
|
@@ -727024,6 +727789,24 @@ function getPatternsByRoot(toolPermissionContext, toolType, behavior) {
|
|
|
727024
727789
|
patternsByRoot.set(root3, patternsForRoot);
|
|
727025
727790
|
}
|
|
727026
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
|
+
}
|
|
727027
727810
|
}
|
|
727028
727811
|
return patternsByRoot;
|
|
727029
727812
|
}
|
|
@@ -727036,7 +727819,7 @@ function matchingRuleForInput(path39, toolPermissionContext, toolType, behavior)
|
|
|
727036
727819
|
for (const [root3, { patternMap, getIg }] of matchersByRoot.entries()) {
|
|
727037
727820
|
const ig = getIg();
|
|
727038
727821
|
const relativePathStr = relativePath(root3 ?? getCwd(), fileAbsolutePath ?? getCwd());
|
|
727039
|
-
if (relativePathStr.startsWith(`..${
|
|
727822
|
+
if (relativePathStr.startsWith(`..${DIR_SEP2}`)) {
|
|
727040
727823
|
continue;
|
|
727041
727824
|
}
|
|
727042
727825
|
if (!relativePathStr) {
|
|
@@ -727497,7 +728280,7 @@ function checkReadableInternalPath(absolutePath, input2) {
|
|
|
727497
728280
|
}
|
|
727498
728281
|
return { behavior: "passthrough", message: "" };
|
|
727499
728282
|
}
|
|
727500
|
-
var import_ignore6, DANGEROUS_FILES2, DANGEROUS_DIRECTORIES2,
|
|
728283
|
+
var import_ignore6, DANGEROUS_FILES2, DANGEROUS_DIRECTORIES2, DIR_SEP2, getClaudeTempDir, getBundledSkillsRoot, getResolvedWorkingDirPaths, MATCHER_RECOMPILE_THRESHOLD = 1e4, MATCHER_CACHE_MAX_ENTRIES = 16, matcherCache;
|
|
727501
728284
|
var init_filesystem = __esm(() => {
|
|
727502
728285
|
init_featureFlags();
|
|
727503
728286
|
init_memoize();
|
|
@@ -727520,6 +728303,7 @@ var init_filesystem = __esm(() => {
|
|
|
727520
728303
|
init_windowsPaths();
|
|
727521
728304
|
init_PermissionUpdate();
|
|
727522
728305
|
init_permissions2();
|
|
728306
|
+
init_symlinkEquivalences();
|
|
727523
728307
|
import_ignore6 = __toESM(require_ignore(), 1);
|
|
727524
728308
|
DANGEROUS_FILES2 = [
|
|
727525
728309
|
".gitconfig",
|
|
@@ -727540,7 +728324,7 @@ var init_filesystem = __esm(() => {
|
|
|
727540
728324
|
".claude",
|
|
727541
728325
|
".husky"
|
|
727542
728326
|
];
|
|
727543
|
-
|
|
728327
|
+
DIR_SEP2 = posix9.sep;
|
|
727544
728328
|
getClaudeTempDir = memoize_default(function getClaudeTempDir2() {
|
|
727545
728329
|
const baseTmpDir = process.env.CLAUDE_CODE_TMPDIR || (getPlatform() === "windows" ? tmpdir15() : "/tmp");
|
|
727546
728330
|
const fs26 = getFsImplementation();
|
|
@@ -762547,6 +763331,14 @@ var init_useBuddyNotification = __esm(() => {
|
|
|
762547
763331
|
jsx_runtime402 = __toESM(require_jsx_runtime(), 1);
|
|
762548
763332
|
});
|
|
762549
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
|
+
|
|
762550
763342
|
// src/hooks/useIdeConnectionStatus.ts
|
|
762551
763343
|
function useIdeConnectionStatus(mcpClients) {
|
|
762552
763344
|
return import_react223.useMemo(() => {
|
|
@@ -764264,6 +765056,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
|
|
|
764264
765056
|
const historyCache = import_react235.useRef([]);
|
|
764265
765057
|
const historyCacheModeFilter = import_react235.useRef(undefined);
|
|
764266
765058
|
const historyIndexRef = import_react235.useRef(0);
|
|
765059
|
+
const recalledValueRef = import_react235.useRef(null);
|
|
764267
765060
|
const initialModeFilterRef = import_react235.useRef(undefined);
|
|
764268
765061
|
const currentInputRef = import_react235.useRef(currentInput);
|
|
764269
765062
|
const pastedContentsRef = import_react235.useRef(pastedContents);
|
|
@@ -764272,6 +765065,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
|
|
|
764272
765065
|
pastedContentsRef.current = pastedContents;
|
|
764273
765066
|
currentModeRef.current = currentMode;
|
|
764274
765067
|
const setInputWithCursor = import_react235.useCallback((value, mode, contents, cursorToStart = false) => {
|
|
765068
|
+
recalledValueRef.current = value;
|
|
764275
765069
|
onSetInput(value, mode, contents);
|
|
764276
765070
|
setCursorOffset?.(cursorToStart ? 0 : value.length);
|
|
764277
765071
|
}, [onSetInput, setCursorOffset]);
|
|
@@ -764367,6 +765161,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
|
|
|
764367
765161
|
setHistoryIndex(0);
|
|
764368
765162
|
historyIndexRef.current = 0;
|
|
764369
765163
|
initialModeFilterRef.current = undefined;
|
|
765164
|
+
recalledValueRef.current = null;
|
|
764370
765165
|
removeNotification("search-history-hint");
|
|
764371
765166
|
historyCache.current = [];
|
|
764372
765167
|
historyCacheModeFilter.current = undefined;
|
|
@@ -764376,6 +765171,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
|
|
|
764376
765171
|
}, [removeNotification]);
|
|
764377
765172
|
return {
|
|
764378
765173
|
historyIndex,
|
|
765174
|
+
historyEdited: computeHistoryEdited(historyIndex, currentInput, recalledValueRef.current),
|
|
764379
765175
|
setHistoryIndex,
|
|
764380
765176
|
onHistoryUp,
|
|
764381
765177
|
onHistoryDown,
|
|
@@ -764383,7 +765179,7 @@ function useArrowKeyHistory(onSetInput, currentInput, pastedContents, setCursorO
|
|
|
764383
765179
|
dismissSearchHint
|
|
764384
765180
|
};
|
|
764385
765181
|
}
|
|
764386
|
-
var import_react235, jsx_runtime414, HISTORY_CHUNK_SIZE = 10, pendingLoad = null, pendingLoadTarget = 0, pendingLoadModeFilter
|
|
765182
|
+
var import_react235, jsx_runtime414, HISTORY_CHUNK_SIZE = 10, pendingLoad = null, pendingLoadTarget = 0, pendingLoadModeFilter;
|
|
764387
765183
|
var init_useArrowKeyHistory = __esm(() => {
|
|
764388
765184
|
init_notifications();
|
|
764389
765185
|
init_ConfigurableShortcutHint();
|
|
@@ -776386,7 +777182,8 @@ function PromptInput({
|
|
|
776386
777182
|
onHistoryUp,
|
|
776387
777183
|
onHistoryDown,
|
|
776388
777184
|
dismissSearchHint,
|
|
776389
|
-
historyIndex
|
|
777185
|
+
historyIndex,
|
|
777186
|
+
historyEdited
|
|
776390
777187
|
} = useArrowKeyHistory((value, historyMode, pastedContents2) => {
|
|
776391
777188
|
onChange(value);
|
|
776392
777189
|
onModeChange(historyMode);
|
|
@@ -776537,7 +777334,7 @@ function PromptInput({
|
|
|
776537
777334
|
agents: agents2,
|
|
776538
777335
|
setSuggestionsState,
|
|
776539
777336
|
suggestionsState,
|
|
776540
|
-
suppressSuggestions: isSearchingHistory
|
|
777337
|
+
suppressSuggestions: computeSuppressSuggestions(isSearchingHistory, historyIndex, historyEdited),
|
|
776541
777338
|
markAccepted,
|
|
776542
777339
|
onModeChange
|
|
776543
777340
|
});
|
|
@@ -797954,7 +798751,10 @@ function useMcpConnectivityStatus(t0) {
|
|
|
797954
798751
|
}
|
|
797955
798752
|
const failedLocalClients = mcpClients.filter(_temp225);
|
|
797956
798753
|
const failedClaudeAiClients = mcpClients.filter(_temp286);
|
|
797957
|
-
|
|
798754
|
+
if (countNoticedServersNowConnected(mcpClients) > 0) {
|
|
798755
|
+
pruneNoticedServersNowConnected(mcpClients);
|
|
798756
|
+
}
|
|
798757
|
+
const needsAuthCount = countNeedsAuthToAnnounce(mcpClients, MCP_NEEDS_AUTH_NOTICE_DEPS);
|
|
797958
798758
|
if (failedLocalClients.length === 0 && failedClaudeAiClients.length === 0 && needsAuthCount === 0) {
|
|
797959
798759
|
return;
|
|
797960
798760
|
}
|
|
@@ -798031,6 +798831,7 @@ function useMcpConnectivityStatus(t0) {
|
|
|
798031
798831
|
}),
|
|
798032
798832
|
priority: "medium"
|
|
798033
798833
|
});
|
|
798834
|
+
markNeedsAuthNoticed(mcpClients, MCP_NEEDS_AUTH_NOTICE_DEPS);
|
|
798034
798835
|
}
|
|
798035
798836
|
};
|
|
798036
798837
|
t32 = [addNotification, mcpClients];
|
|
@@ -798050,16 +798851,21 @@ function _temp286(client_0) {
|
|
|
798050
798851
|
function _temp225(client8) {
|
|
798051
798852
|
return client8.type === "failed" && client8.config.type !== "sse-ide" && client8.config.type !== "ws-ide" && client8.config.type !== "claudeai-proxy";
|
|
798052
798853
|
}
|
|
798053
|
-
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;
|
|
798054
798855
|
var init_useMcpConnectivityStatus = __esm(() => {
|
|
798055
798856
|
init_notifications();
|
|
798056
798857
|
init_state();
|
|
798057
798858
|
init_ink2();
|
|
798058
798859
|
init_claudeai();
|
|
798860
|
+
init_mcpNeedsAuthNotice();
|
|
798059
798861
|
import_compiler_runtime326 = __toESM(require_compiler_runtime(), 1);
|
|
798060
798862
|
import_react303 = __toESM(require_react(), 1);
|
|
798061
798863
|
jsx_runtime455 = __toESM(require_jsx_runtime(), 1);
|
|
798062
798864
|
EMPTY_MCP_CLIENTS = [];
|
|
798865
|
+
MCP_NEEDS_AUTH_NOTICE_DEPS = {
|
|
798866
|
+
hasEverConnected: hasClaudeAiMcpEverConnected,
|
|
798867
|
+
connectedThisSession: isClaudeAiMcpCurrentlyConnected
|
|
798868
|
+
};
|
|
798063
798869
|
});
|
|
798064
798870
|
|
|
798065
798871
|
// src/hooks/notifs/useAutoModeUnavailableNotification.ts
|
|
@@ -807293,13 +808099,13 @@ var init_bootstrap = __esm(() => {
|
|
|
807293
808099
|
});
|
|
807294
808100
|
|
|
807295
808101
|
// src/utils/warningHandler.ts
|
|
807296
|
-
import { posix as
|
|
808102
|
+
import { posix as posix10, win32 as win324 } from "path";
|
|
807297
808103
|
function isRunningFromBuildDirectory() {
|
|
807298
808104
|
let invokedPath = process.argv[1] || "";
|
|
807299
808105
|
let execPath2 = process.execPath || process.argv[0] || "";
|
|
807300
808106
|
if (getPlatform() === "windows") {
|
|
807301
|
-
invokedPath = invokedPath.split(win324.sep).join(
|
|
807302
|
-
execPath2 = execPath2.split(win324.sep).join(
|
|
808107
|
+
invokedPath = invokedPath.split(win324.sep).join(posix10.sep);
|
|
808108
|
+
execPath2 = execPath2.split(win324.sep).join(posix10.sep);
|
|
807303
808109
|
}
|
|
807304
808110
|
const pathsToCheck = [invokedPath, execPath2];
|
|
807305
808111
|
const buildDirs = [
|
|
@@ -824005,11 +824811,14 @@ async function mcpListHandler() {
|
|
|
824005
824811
|
}), {
|
|
824006
824812
|
concurrency: getMcpServerConnectionBatchSize()
|
|
824007
824813
|
});
|
|
824814
|
+
const displayConfigs = getDisplayServers(configs, resolveUnexpandedMcpServers);
|
|
824008
824815
|
for (const {
|
|
824009
824816
|
name: name3,
|
|
824010
|
-
server,
|
|
824011
824817
|
status: status2
|
|
824012
824818
|
} of results) {
|
|
824819
|
+
const server = displayConfigs[name3];
|
|
824820
|
+
if (!server)
|
|
824821
|
+
continue;
|
|
824013
824822
|
if (server.type === "sse") {
|
|
824014
824823
|
console.log(`${name3}: ${server.url} (SSE) - ${status2}`);
|
|
824015
824824
|
} else if (server.type === "http") {
|
|
@@ -824036,12 +824845,13 @@ async function mcpGetHandler(name3) {
|
|
|
824036
824845
|
console.log(` Scope: ${getScopeLabel(server.scope)}`);
|
|
824037
824846
|
const status2 = await checkMcpServerHealth(name3, server);
|
|
824038
824847
|
console.log(` Status: ${status2}`);
|
|
824039
|
-
|
|
824848
|
+
const display = getDisplayConfig(name3, server, resolveUnexpandedMcpServers);
|
|
824849
|
+
if (display.type === "sse") {
|
|
824040
824850
|
console.log(` Type: sse`);
|
|
824041
|
-
console.log(` URL: ${
|
|
824042
|
-
if (
|
|
824851
|
+
console.log(` URL: ${display.url}`);
|
|
824852
|
+
if (display.headers) {
|
|
824043
824853
|
console.log(" Headers:");
|
|
824044
|
-
for (const [key4, value] of Object.entries(
|
|
824854
|
+
for (const [key4, value] of Object.entries(display.headers)) {
|
|
824045
824855
|
console.log(` ${key4}: ${value}`);
|
|
824046
824856
|
}
|
|
824047
824857
|
}
|
|
@@ -824057,12 +824867,12 @@ async function mcpGetHandler(name3) {
|
|
|
824057
824867
|
parts.push(`callback_port ${server.oauth.callbackPort}`);
|
|
824058
824868
|
console.log(` OAuth: ${parts.join(", ")}`);
|
|
824059
824869
|
}
|
|
824060
|
-
} else if (
|
|
824870
|
+
} else if (display.type === "http") {
|
|
824061
824871
|
console.log(` Type: http`);
|
|
824062
|
-
console.log(` URL: ${
|
|
824063
|
-
if (
|
|
824872
|
+
console.log(` URL: ${display.url}`);
|
|
824873
|
+
if (display.headers) {
|
|
824064
824874
|
console.log(" Headers:");
|
|
824065
|
-
for (const [key4, value] of Object.entries(
|
|
824875
|
+
for (const [key4, value] of Object.entries(display.headers)) {
|
|
824066
824876
|
console.log(` ${key4}: ${value}`);
|
|
824067
824877
|
}
|
|
824068
824878
|
}
|
|
@@ -824078,14 +824888,14 @@ async function mcpGetHandler(name3) {
|
|
|
824078
824888
|
parts.push(`callback_port ${server.oauth.callbackPort}`);
|
|
824079
824889
|
console.log(` OAuth: ${parts.join(", ")}`);
|
|
824080
824890
|
}
|
|
824081
|
-
} else if (
|
|
824891
|
+
} else if (display.type === "stdio") {
|
|
824082
824892
|
console.log(` Type: stdio`);
|
|
824083
|
-
console.log(` Command: ${
|
|
824084
|
-
const args = Array.isArray(
|
|
824893
|
+
console.log(` Command: ${display.command}`);
|
|
824894
|
+
const args = Array.isArray(display.args) ? display.args : [];
|
|
824085
824895
|
console.log(` Args: ${args.join(" ")}`);
|
|
824086
|
-
if (
|
|
824896
|
+
if (display.env) {
|
|
824087
824897
|
console.log(" Environment:");
|
|
824088
|
-
for (const [key4, value] of Object.entries(
|
|
824898
|
+
for (const [key4, value] of Object.entries(display.env)) {
|
|
824089
824899
|
console.log(` ${key4}=${value}`);
|
|
824090
824900
|
}
|
|
824091
824901
|
}
|
|
@@ -824212,7 +825022,7 @@ After authorizing, paste the full redirect URL here and press Enter:`);
|
|
|
824212
825022
|
});
|
|
824213
825023
|
cliOk(`Successfully authenticated with MCP server "${name3}".`);
|
|
824214
825024
|
} catch (error52) {
|
|
824215
|
-
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)}`);
|
|
824216
825026
|
}
|
|
824217
825027
|
}
|
|
824218
825028
|
async function mcpLogoutHandler(name3) {
|
|
@@ -824245,6 +825055,7 @@ var init_mcp5 = __esm(() => {
|
|
|
824245
825055
|
init_auth11();
|
|
824246
825056
|
init_client12();
|
|
824247
825057
|
init_config6();
|
|
825058
|
+
init_redaction();
|
|
824248
825059
|
init_utils9();
|
|
824249
825060
|
init_normalization();
|
|
824250
825061
|
init_AppState();
|