@qwen-code/qwen-code 0.9.0-preview.3 → 0.9.0
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/cli.js +525 -512
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -26270,21 +26270,21 @@ var init_from = __esm({
|
|
|
26270
26270
|
init_fetch_blob();
|
|
26271
26271
|
({ stat } = fs2);
|
|
26272
26272
|
blobFromSync = /* @__PURE__ */ __name((path123, type) => fromBlob(statSync(path123), path123, type), "blobFromSync");
|
|
26273
|
-
blobFrom = /* @__PURE__ */ __name((path123, type) => stat(path123).then((
|
|
26274
|
-
fileFrom = /* @__PURE__ */ __name((path123, type) => stat(path123).then((
|
|
26273
|
+
blobFrom = /* @__PURE__ */ __name((path123, type) => stat(path123).then((stat10) => fromBlob(stat10, path123, type)), "blobFrom");
|
|
26274
|
+
fileFrom = /* @__PURE__ */ __name((path123, type) => stat(path123).then((stat10) => fromFile(stat10, path123, type)), "fileFrom");
|
|
26275
26275
|
fileFromSync = /* @__PURE__ */ __name((path123, type) => fromFile(statSync(path123), path123, type), "fileFromSync");
|
|
26276
|
-
fromBlob = /* @__PURE__ */ __name((
|
|
26276
|
+
fromBlob = /* @__PURE__ */ __name((stat10, path123, type = "") => new fetch_blob_default([new BlobDataItem({
|
|
26277
26277
|
path: path123,
|
|
26278
|
-
size:
|
|
26279
|
-
lastModified:
|
|
26278
|
+
size: stat10.size,
|
|
26279
|
+
lastModified: stat10.mtimeMs,
|
|
26280
26280
|
start: 0
|
|
26281
26281
|
})], { type }), "fromBlob");
|
|
26282
|
-
fromFile = /* @__PURE__ */ __name((
|
|
26282
|
+
fromFile = /* @__PURE__ */ __name((stat10, path123, type = "") => new file_default([new BlobDataItem({
|
|
26283
26283
|
path: path123,
|
|
26284
|
-
size:
|
|
26285
|
-
lastModified:
|
|
26284
|
+
size: stat10.size,
|
|
26285
|
+
lastModified: stat10.mtimeMs,
|
|
26286
26286
|
start: 0
|
|
26287
|
-
})], basename(path123), { type, lastModified:
|
|
26287
|
+
})], basename(path123), { type, lastModified: stat10.mtimeMs }), "fromFile");
|
|
26288
26288
|
BlobDataItem = class _BlobDataItem {
|
|
26289
26289
|
static {
|
|
26290
26290
|
__name(this, "BlobDataItem");
|
|
@@ -123529,18 +123529,18 @@ var require_async = __commonJS({
|
|
|
123529
123529
|
];
|
|
123530
123530
|
}, "defaultPaths");
|
|
123531
123531
|
var defaultIsFile = /* @__PURE__ */ __name(function isFile3(file, cb) {
|
|
123532
|
-
fs110.stat(file, function(err,
|
|
123532
|
+
fs110.stat(file, function(err, stat10) {
|
|
123533
123533
|
if (!err) {
|
|
123534
|
-
return cb(null,
|
|
123534
|
+
return cb(null, stat10.isFile() || stat10.isFIFO());
|
|
123535
123535
|
}
|
|
123536
123536
|
if (err.code === "ENOENT" || err.code === "ENOTDIR") return cb(null, false);
|
|
123537
123537
|
return cb(err);
|
|
123538
123538
|
});
|
|
123539
123539
|
}, "isFile");
|
|
123540
123540
|
var defaultIsDir = /* @__PURE__ */ __name(function isDirectory(dir, cb) {
|
|
123541
|
-
fs110.stat(dir, function(err,
|
|
123541
|
+
fs110.stat(dir, function(err, stat10) {
|
|
123542
123542
|
if (!err) {
|
|
123543
|
-
return cb(null,
|
|
123543
|
+
return cb(null, stat10.isDirectory());
|
|
123544
123544
|
}
|
|
123545
123545
|
if (err.code === "ENOENT" || err.code === "ENOTDIR") return cb(null, false);
|
|
123546
123546
|
return cb(err);
|
|
@@ -124036,21 +124036,21 @@ var require_sync = __commonJS({
|
|
|
124036
124036
|
}, "defaultPaths");
|
|
124037
124037
|
var defaultIsFile = /* @__PURE__ */ __name(function isFile3(file) {
|
|
124038
124038
|
try {
|
|
124039
|
-
var
|
|
124039
|
+
var stat10 = fs110.statSync(file, { throwIfNoEntry: false });
|
|
124040
124040
|
} catch (e4) {
|
|
124041
124041
|
if (e4 && (e4.code === "ENOENT" || e4.code === "ENOTDIR")) return false;
|
|
124042
124042
|
throw e4;
|
|
124043
124043
|
}
|
|
124044
|
-
return !!
|
|
124044
|
+
return !!stat10 && (stat10.isFile() || stat10.isFIFO());
|
|
124045
124045
|
}, "isFile");
|
|
124046
124046
|
var defaultIsDir = /* @__PURE__ */ __name(function isDirectory(dir) {
|
|
124047
124047
|
try {
|
|
124048
|
-
var
|
|
124048
|
+
var stat10 = fs110.statSync(dir, { throwIfNoEntry: false });
|
|
124049
124049
|
} catch (e4) {
|
|
124050
124050
|
if (e4 && (e4.code === "ENOENT" || e4.code === "ENOTDIR")) return false;
|
|
124051
124051
|
throw e4;
|
|
124052
124052
|
}
|
|
124053
|
-
return !!
|
|
124053
|
+
return !!stat10 && stat10.isDirectory();
|
|
124054
124054
|
}, "isDirectory");
|
|
124055
124055
|
var defaultRealpathSync = /* @__PURE__ */ __name(function realpathSync8(x3) {
|
|
124056
124056
|
try {
|
|
@@ -124476,14 +124476,14 @@ var require_require_in_the_middle = __commonJS({
|
|
|
124476
124476
|
moduleName2 = parsedPath.name;
|
|
124477
124477
|
basedir = parsedPath.dir;
|
|
124478
124478
|
} else {
|
|
124479
|
-
const
|
|
124480
|
-
if (
|
|
124479
|
+
const stat10 = moduleDetailsFromPath(filename);
|
|
124480
|
+
if (stat10 === void 0) {
|
|
124481
124481
|
debug3("could not parse filename: %s", filename);
|
|
124482
124482
|
return exports3;
|
|
124483
124483
|
}
|
|
124484
|
-
moduleName2 =
|
|
124485
|
-
basedir =
|
|
124486
|
-
const fullModuleName = resolveModuleName(
|
|
124484
|
+
moduleName2 = stat10.name;
|
|
124485
|
+
basedir = stat10.basedir;
|
|
124486
|
+
const fullModuleName = resolveModuleName(stat10);
|
|
124487
124487
|
debug3("resolved filename to module: %s (id: %s, resolved: %s, basedir: %s)", moduleName2, id, fullModuleName, basedir);
|
|
124488
124488
|
let matchFound = false;
|
|
124489
124489
|
if (hasWhitelist) {
|
|
@@ -124547,9 +124547,9 @@ var require_require_in_the_middle = __commonJS({
|
|
|
124547
124547
|
}
|
|
124548
124548
|
}
|
|
124549
124549
|
};
|
|
124550
|
-
function resolveModuleName(
|
|
124551
|
-
const normalizedPath = path123.sep !== "/" ?
|
|
124552
|
-
return path123.posix.join(
|
|
124550
|
+
function resolveModuleName(stat10) {
|
|
124551
|
+
const normalizedPath = path123.sep !== "/" ? stat10.path.split(path123.sep).join("/") : stat10.path;
|
|
124552
|
+
return path123.posix.join(stat10.name, normalizedPath).replace(normalize11, "");
|
|
124553
124553
|
}
|
|
124554
124554
|
__name(resolveModuleName, "resolveModuleName");
|
|
124555
124555
|
}
|
|
@@ -155848,7 +155848,7 @@ __export(geminiContentGenerator_exports, {
|
|
|
155848
155848
|
createGeminiContentGenerator: () => createGeminiContentGenerator
|
|
155849
155849
|
});
|
|
155850
155850
|
function createGeminiContentGenerator(config2, gcConfig) {
|
|
155851
|
-
const version2 = "0.9.0
|
|
155851
|
+
const version2 = "0.9.0";
|
|
155852
155852
|
const userAgent2 = config2.userAgent || `QwenCode/${version2} (${process.platform}; ${process.arch})`;
|
|
155853
155853
|
const baseHeaders = {
|
|
155854
155854
|
"User-Agent": userAgent2
|
|
@@ -187415,12 +187415,12 @@ var require_src36 = __commonJS({
|
|
|
187415
187415
|
function check2(path123, isFile3, isDirectory) {
|
|
187416
187416
|
log(`checking %s`, path123);
|
|
187417
187417
|
try {
|
|
187418
|
-
const
|
|
187419
|
-
if (
|
|
187418
|
+
const stat10 = fs_1.statSync(path123);
|
|
187419
|
+
if (stat10.isFile() && isFile3) {
|
|
187420
187420
|
log(`[OK] path represents a file`);
|
|
187421
187421
|
return true;
|
|
187422
187422
|
}
|
|
187423
|
-
if (
|
|
187423
|
+
if (stat10.isDirectory() && isDirectory) {
|
|
187424
187424
|
log(`[OK] path represents a directory`);
|
|
187425
187425
|
return true;
|
|
187426
187426
|
}
|
|
@@ -203472,16 +203472,16 @@ var require_windows = __commonJS({
|
|
|
203472
203472
|
return false;
|
|
203473
203473
|
}
|
|
203474
203474
|
__name(checkPathExt, "checkPathExt");
|
|
203475
|
-
function checkStat(
|
|
203476
|
-
if (!
|
|
203475
|
+
function checkStat(stat10, path123, options2) {
|
|
203476
|
+
if (!stat10.isSymbolicLink() && !stat10.isFile()) {
|
|
203477
203477
|
return false;
|
|
203478
203478
|
}
|
|
203479
203479
|
return checkPathExt(path123, options2);
|
|
203480
203480
|
}
|
|
203481
203481
|
__name(checkStat, "checkStat");
|
|
203482
203482
|
function isexe(path123, options2, cb) {
|
|
203483
|
-
fs110.stat(path123, function(er2,
|
|
203484
|
-
cb(er2, er2 ? false : checkStat(
|
|
203483
|
+
fs110.stat(path123, function(er2, stat10) {
|
|
203484
|
+
cb(er2, er2 ? false : checkStat(stat10, path123, options2));
|
|
203485
203485
|
});
|
|
203486
203486
|
}
|
|
203487
203487
|
__name(isexe, "isexe");
|
|
@@ -203500,8 +203500,8 @@ var require_mode = __commonJS({
|
|
|
203500
203500
|
isexe.sync = sync2;
|
|
203501
203501
|
var fs110 = __require("fs");
|
|
203502
203502
|
function isexe(path123, options2, cb) {
|
|
203503
|
-
fs110.stat(path123, function(er2,
|
|
203504
|
-
cb(er2, er2 ? false : checkStat(
|
|
203503
|
+
fs110.stat(path123, function(er2, stat10) {
|
|
203504
|
+
cb(er2, er2 ? false : checkStat(stat10, options2));
|
|
203505
203505
|
});
|
|
203506
203506
|
}
|
|
203507
203507
|
__name(isexe, "isexe");
|
|
@@ -203509,14 +203509,14 @@ var require_mode = __commonJS({
|
|
|
203509
203509
|
return checkStat(fs110.statSync(path123), options2);
|
|
203510
203510
|
}
|
|
203511
203511
|
__name(sync2, "sync");
|
|
203512
|
-
function checkStat(
|
|
203513
|
-
return
|
|
203512
|
+
function checkStat(stat10, options2) {
|
|
203513
|
+
return stat10.isFile() && checkMode(stat10, options2);
|
|
203514
203514
|
}
|
|
203515
203515
|
__name(checkStat, "checkStat");
|
|
203516
|
-
function checkMode(
|
|
203517
|
-
var mod2 =
|
|
203518
|
-
var uid =
|
|
203519
|
-
var gid =
|
|
203516
|
+
function checkMode(stat10, options2) {
|
|
203517
|
+
var mod2 = stat10.mode;
|
|
203518
|
+
var uid = stat10.uid;
|
|
203519
|
+
var gid = stat10.gid;
|
|
203520
203520
|
var myUid = options2.uid !== void 0 ? options2.uid : process.getuid && process.getuid();
|
|
203521
203521
|
var myGid = options2.gid !== void 0 ? options2.gid : process.getgid && process.getgid();
|
|
203522
203522
|
var u2 = parseInt("100", 8);
|
|
@@ -204647,14 +204647,14 @@ var init_ide_client = __esm({
|
|
|
204647
204647
|
const fileContents = await Promise.all(lockFiles.map(async (file) => {
|
|
204648
204648
|
const fullPath = path32.join(ideDir, file);
|
|
204649
204649
|
try {
|
|
204650
|
-
const
|
|
204650
|
+
const stat10 = await fs32.promises.stat(fullPath);
|
|
204651
204651
|
const content = await fs32.promises.readFile(fullPath, "utf8");
|
|
204652
204652
|
try {
|
|
204653
204653
|
const parsed = JSON.parse(content);
|
|
204654
|
-
return { file, mtimeMs:
|
|
204654
|
+
return { file, mtimeMs: stat10.mtimeMs, parsed };
|
|
204655
204655
|
} catch (e4) {
|
|
204656
204656
|
logger.debug("Failed to parse JSON from lock file: ", e4);
|
|
204657
|
-
return { file, mtimeMs:
|
|
204657
|
+
return { file, mtimeMs: stat10.mtimeMs, parsed: void 0 };
|
|
204658
204658
|
}
|
|
204659
204659
|
} catch (e4) {
|
|
204660
204660
|
logger.debug("Failed to read/stat IDE lock file:", e4);
|
|
@@ -210920,6 +210920,82 @@ function getMCPServerStatus(serverName) {
|
|
|
210920
210920
|
function getMCPDiscoveryState() {
|
|
210921
210921
|
return mcpDiscoveryState;
|
|
210922
210922
|
}
|
|
210923
|
+
function extractWWWAuthenticateHeader(errorString) {
|
|
210924
|
+
const patterns = [
|
|
210925
|
+
/www-authenticate:\s*([^\n\r]+)/i,
|
|
210926
|
+
/WWW-Authenticate:\s*([^\n\r]+)/i,
|
|
210927
|
+
/"www-authenticate":\s*"([^"]+)"/i,
|
|
210928
|
+
/'www-authenticate':\s*'([^']+)'/i
|
|
210929
|
+
];
|
|
210930
|
+
for (const pattern of patterns) {
|
|
210931
|
+
const match2 = errorString.match(pattern);
|
|
210932
|
+
if (match2) {
|
|
210933
|
+
return match2[1].trim();
|
|
210934
|
+
}
|
|
210935
|
+
}
|
|
210936
|
+
return null;
|
|
210937
|
+
}
|
|
210938
|
+
async function handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthenticate) {
|
|
210939
|
+
try {
|
|
210940
|
+
console.log(`\u{1F510} '${mcpServerName}' requires OAuth authentication`);
|
|
210941
|
+
let oauthConfig;
|
|
210942
|
+
const resourceMetadataUri = OAuthUtils.parseWWWAuthenticateHeader(wwwAuthenticate);
|
|
210943
|
+
if (resourceMetadataUri) {
|
|
210944
|
+
oauthConfig = await OAuthUtils.discoverOAuthConfig(resourceMetadataUri);
|
|
210945
|
+
} else if (hasNetworkTransport(mcpServerConfig)) {
|
|
210946
|
+
const serverUrl2 = new URL(mcpServerConfig.httpUrl || mcpServerConfig.url);
|
|
210947
|
+
const baseUrl = `${serverUrl2.protocol}//${serverUrl2.host}`;
|
|
210948
|
+
oauthConfig = await OAuthUtils.discoverOAuthConfig(baseUrl);
|
|
210949
|
+
}
|
|
210950
|
+
if (!oauthConfig) {
|
|
210951
|
+
console.error(`\u274C Could not configure OAuth for '${mcpServerName}' - please authenticate manually with /mcp auth ${mcpServerName}`);
|
|
210952
|
+
return false;
|
|
210953
|
+
}
|
|
210954
|
+
const oauthAuthConfig = {
|
|
210955
|
+
enabled: true,
|
|
210956
|
+
authorizationUrl: oauthConfig.authorizationUrl,
|
|
210957
|
+
tokenUrl: oauthConfig.tokenUrl,
|
|
210958
|
+
scopes: oauthConfig.scopes || []
|
|
210959
|
+
};
|
|
210960
|
+
const serverUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
|
|
210961
|
+
console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
|
|
210962
|
+
const authProvider = new MCPOAuthProvider(new MCPOAuthTokenStorage());
|
|
210963
|
+
await authProvider.authenticate(mcpServerName, oauthAuthConfig, serverUrl);
|
|
210964
|
+
console.log(`OAuth authentication successful for server '${mcpServerName}'`);
|
|
210965
|
+
return true;
|
|
210966
|
+
} catch (error2) {
|
|
210967
|
+
console.error(`Failed to handle automatic OAuth for server '${mcpServerName}': ${getErrorMessage(error2)}`);
|
|
210968
|
+
return false;
|
|
210969
|
+
}
|
|
210970
|
+
}
|
|
210971
|
+
async function createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken) {
|
|
210972
|
+
try {
|
|
210973
|
+
if (mcpServerConfig.httpUrl) {
|
|
210974
|
+
const oauthTransportOptions = {
|
|
210975
|
+
requestInit: {
|
|
210976
|
+
headers: {
|
|
210977
|
+
...mcpServerConfig.headers,
|
|
210978
|
+
Authorization: `Bearer ${accessToken}`
|
|
210979
|
+
}
|
|
210980
|
+
}
|
|
210981
|
+
};
|
|
210982
|
+
return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), oauthTransportOptions);
|
|
210983
|
+
} else if (mcpServerConfig.url) {
|
|
210984
|
+
return new SSEClientTransport(new URL(mcpServerConfig.url), {
|
|
210985
|
+
requestInit: {
|
|
210986
|
+
headers: {
|
|
210987
|
+
...mcpServerConfig.headers,
|
|
210988
|
+
Authorization: `Bearer ${accessToken}`
|
|
210989
|
+
}
|
|
210990
|
+
}
|
|
210991
|
+
});
|
|
210992
|
+
}
|
|
210993
|
+
return null;
|
|
210994
|
+
} catch (error2) {
|
|
210995
|
+
console.error(`Failed to create OAuth transport for server '${mcpServerName}': ${getErrorMessage(error2)}`);
|
|
210996
|
+
return null;
|
|
210997
|
+
}
|
|
210998
|
+
}
|
|
210923
210999
|
function populateMcpServerCommand(mcpServers, mcpServerCommand) {
|
|
210924
211000
|
if (mcpServerCommand) {
|
|
210925
211001
|
const cmd = mcpServerCommand;
|
|
@@ -210934,6 +211010,32 @@ function populateMcpServerCommand(mcpServers, mcpServerCommand) {
|
|
|
210934
211010
|
}
|
|
210935
211011
|
return mcpServers;
|
|
210936
211012
|
}
|
|
211013
|
+
async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext, cliConfig, sendSdkMcpMessage) {
|
|
211014
|
+
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING);
|
|
211015
|
+
let mcpClient;
|
|
211016
|
+
try {
|
|
211017
|
+
mcpClient = await connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext, sendSdkMcpMessage);
|
|
211018
|
+
mcpClient.onerror = (error2) => {
|
|
211019
|
+
console.error(`MCP ERROR (${mcpServerName}):`, error2.toString());
|
|
211020
|
+
updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
|
|
211021
|
+
};
|
|
211022
|
+
const prompts3 = await discoverPrompts(mcpServerName, mcpClient, promptRegistry);
|
|
211023
|
+
const tools = await discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfig);
|
|
211024
|
+
if (prompts3.length === 0 && tools.length === 0) {
|
|
211025
|
+
throw new Error("No prompts or tools found on the server.");
|
|
211026
|
+
}
|
|
211027
|
+
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTED);
|
|
211028
|
+
for (const tool of tools) {
|
|
211029
|
+
toolRegistry.registerTool(tool);
|
|
211030
|
+
}
|
|
211031
|
+
} catch (error2) {
|
|
211032
|
+
if (mcpClient) {
|
|
211033
|
+
mcpClient.close();
|
|
211034
|
+
}
|
|
211035
|
+
console.error(`Error connecting to MCP server '${mcpServerName}': ${getErrorMessage(error2)}`);
|
|
211036
|
+
updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
|
|
211037
|
+
}
|
|
211038
|
+
}
|
|
210937
211039
|
async function discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfig) {
|
|
210938
211040
|
try {
|
|
210939
211041
|
const mcpCallableTool = mcpToTool(mcpClient, {
|
|
@@ -210999,6 +211101,241 @@ async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, promptParam
|
|
|
210999
211101
|
throw error2;
|
|
211000
211102
|
}
|
|
211001
211103
|
}
|
|
211104
|
+
function hasNetworkTransport(config2) {
|
|
211105
|
+
return !!(config2.url || config2.httpUrl);
|
|
211106
|
+
}
|
|
211107
|
+
async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext, sendSdkMcpMessage) {
|
|
211108
|
+
const mcpClient = new Client({
|
|
211109
|
+
name: "qwen-code-mcp-client",
|
|
211110
|
+
version: "0.0.1"
|
|
211111
|
+
});
|
|
211112
|
+
mcpClient.registerCapabilities({
|
|
211113
|
+
roots: {
|
|
211114
|
+
listChanged: true
|
|
211115
|
+
}
|
|
211116
|
+
});
|
|
211117
|
+
mcpClient.setRequestHandler(ListRootsRequestSchema, async () => {
|
|
211118
|
+
const roots = [];
|
|
211119
|
+
for (const dir of workspaceContext.getDirectories()) {
|
|
211120
|
+
roots.push({
|
|
211121
|
+
uri: pathToFileURL(dir).toString(),
|
|
211122
|
+
name: basename11(dir)
|
|
211123
|
+
});
|
|
211124
|
+
}
|
|
211125
|
+
return {
|
|
211126
|
+
roots
|
|
211127
|
+
};
|
|
211128
|
+
});
|
|
211129
|
+
let unlistenDirectories = workspaceContext.onDirectoriesChanged(async () => {
|
|
211130
|
+
try {
|
|
211131
|
+
await mcpClient.notification({
|
|
211132
|
+
method: "notifications/roots/list_changed"
|
|
211133
|
+
});
|
|
211134
|
+
} catch (_2) {
|
|
211135
|
+
unlistenDirectories?.();
|
|
211136
|
+
unlistenDirectories = void 0;
|
|
211137
|
+
}
|
|
211138
|
+
});
|
|
211139
|
+
const oldOnClose = mcpClient.onclose;
|
|
211140
|
+
mcpClient.onclose = () => {
|
|
211141
|
+
oldOnClose?.();
|
|
211142
|
+
unlistenDirectories?.();
|
|
211143
|
+
unlistenDirectories = void 0;
|
|
211144
|
+
};
|
|
211145
|
+
try {
|
|
211146
|
+
const transport = await createTransport(mcpServerName, mcpServerConfig, debugMode, sendSdkMcpMessage);
|
|
211147
|
+
try {
|
|
211148
|
+
await mcpClient.connect(transport, {
|
|
211149
|
+
timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC
|
|
211150
|
+
});
|
|
211151
|
+
return mcpClient;
|
|
211152
|
+
} catch (error2) {
|
|
211153
|
+
await transport.close();
|
|
211154
|
+
throw error2;
|
|
211155
|
+
}
|
|
211156
|
+
} catch (error2) {
|
|
211157
|
+
const errorString = String(error2);
|
|
211158
|
+
if (errorString.includes("401") && hasNetworkTransport(mcpServerConfig)) {
|
|
211159
|
+
mcpServerRequiresOAuth.set(mcpServerName, true);
|
|
211160
|
+
const shouldTriggerOAuth = mcpServerConfig.httpUrl || mcpServerConfig.oauth?.enabled;
|
|
211161
|
+
if (!shouldTriggerOAuth) {
|
|
211162
|
+
const tokenStorage = new MCPOAuthTokenStorage();
|
|
211163
|
+
const credentials = await tokenStorage.getCredentials(mcpServerName);
|
|
211164
|
+
if (credentials) {
|
|
211165
|
+
const authProvider = new MCPOAuthProvider(tokenStorage);
|
|
211166
|
+
const hasStoredTokens = await authProvider.getValidToken(mcpServerName, {
|
|
211167
|
+
// Pass client ID if available
|
|
211168
|
+
clientId: credentials.clientId
|
|
211169
|
+
});
|
|
211170
|
+
if (hasStoredTokens) {
|
|
211171
|
+
console.log(`Stored OAuth token for SSE server '${mcpServerName}' was rejected. Please re-authenticate using: /mcp auth ${mcpServerName}`);
|
|
211172
|
+
} else {
|
|
211173
|
+
console.log(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. Please authenticate using: /mcp auth ${mcpServerName}`);
|
|
211174
|
+
}
|
|
211175
|
+
}
|
|
211176
|
+
throw new Error(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. Please authenticate using: /mcp auth ${mcpServerName}`);
|
|
211177
|
+
}
|
|
211178
|
+
let wwwAuthenticate = extractWWWAuthenticateHeader(errorString);
|
|
211179
|
+
if (!wwwAuthenticate && hasNetworkTransport(mcpServerConfig)) {
|
|
211180
|
+
console.log(`No www-authenticate header in error, trying to fetch it from server...`);
|
|
211181
|
+
try {
|
|
211182
|
+
const urlToFetch = mcpServerConfig.httpUrl || mcpServerConfig.url;
|
|
211183
|
+
const response = await fetch(urlToFetch, {
|
|
211184
|
+
method: "HEAD",
|
|
211185
|
+
headers: {
|
|
211186
|
+
Accept: mcpServerConfig.httpUrl ? "application/json" : "text/event-stream"
|
|
211187
|
+
},
|
|
211188
|
+
signal: AbortSignal.timeout(5e3)
|
|
211189
|
+
});
|
|
211190
|
+
if (response.status === 401) {
|
|
211191
|
+
wwwAuthenticate = response.headers.get("www-authenticate");
|
|
211192
|
+
if (wwwAuthenticate) {
|
|
211193
|
+
console.log(`Found www-authenticate header from server: ${wwwAuthenticate}`);
|
|
211194
|
+
}
|
|
211195
|
+
}
|
|
211196
|
+
} catch (fetchError) {
|
|
211197
|
+
console.debug(`Failed to fetch www-authenticate header: ${getErrorMessage(fetchError)}`);
|
|
211198
|
+
}
|
|
211199
|
+
}
|
|
211200
|
+
if (wwwAuthenticate) {
|
|
211201
|
+
console.log(`Received 401 with www-authenticate header: ${wwwAuthenticate}`);
|
|
211202
|
+
const oauthSuccess = await handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthenticate);
|
|
211203
|
+
if (oauthSuccess) {
|
|
211204
|
+
console.log(`Retrying connection to '${mcpServerName}' with OAuth token...`);
|
|
211205
|
+
const tokenStorage = new MCPOAuthTokenStorage();
|
|
211206
|
+
const credentials = await tokenStorage.getCredentials(mcpServerName);
|
|
211207
|
+
if (credentials) {
|
|
211208
|
+
const authProvider = new MCPOAuthProvider(tokenStorage);
|
|
211209
|
+
const accessToken = await authProvider.getValidToken(mcpServerName, {
|
|
211210
|
+
// Pass client ID if available
|
|
211211
|
+
clientId: credentials.clientId
|
|
211212
|
+
});
|
|
211213
|
+
if (accessToken) {
|
|
211214
|
+
const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
|
|
211215
|
+
if (oauthTransport) {
|
|
211216
|
+
try {
|
|
211217
|
+
await mcpClient.connect(oauthTransport, {
|
|
211218
|
+
timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC
|
|
211219
|
+
});
|
|
211220
|
+
return mcpClient;
|
|
211221
|
+
} catch (retryError) {
|
|
211222
|
+
console.error(`Failed to connect with OAuth token: ${getErrorMessage(retryError)}`);
|
|
211223
|
+
throw retryError;
|
|
211224
|
+
}
|
|
211225
|
+
} else {
|
|
211226
|
+
console.error(`Failed to create OAuth transport for server '${mcpServerName}'`);
|
|
211227
|
+
throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
|
|
211228
|
+
}
|
|
211229
|
+
} else {
|
|
211230
|
+
console.error(`Failed to get OAuth token for server '${mcpServerName}'`);
|
|
211231
|
+
throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
|
|
211232
|
+
}
|
|
211233
|
+
} else {
|
|
211234
|
+
console.error(`Failed to get credentials for server '${mcpServerName}' after successful OAuth authentication`);
|
|
211235
|
+
throw new Error(`Failed to get credentials for server '${mcpServerName}' after successful OAuth authentication`);
|
|
211236
|
+
}
|
|
211237
|
+
} else {
|
|
211238
|
+
console.error(`Failed to handle automatic OAuth for server '${mcpServerName}'`);
|
|
211239
|
+
throw new Error(`Failed to handle automatic OAuth for server '${mcpServerName}'`);
|
|
211240
|
+
}
|
|
211241
|
+
} else {
|
|
211242
|
+
const shouldTryDiscovery = mcpServerConfig.httpUrl || mcpServerConfig.oauth?.enabled;
|
|
211243
|
+
if (!shouldTryDiscovery) {
|
|
211244
|
+
const tokenStorage = new MCPOAuthTokenStorage();
|
|
211245
|
+
const credentials = await tokenStorage.getCredentials(mcpServerName);
|
|
211246
|
+
if (credentials) {
|
|
211247
|
+
const authProvider = new MCPOAuthProvider(tokenStorage);
|
|
211248
|
+
const hasStoredTokens = await authProvider.getValidToken(mcpServerName, {
|
|
211249
|
+
// Pass client ID if available
|
|
211250
|
+
clientId: credentials.clientId
|
|
211251
|
+
});
|
|
211252
|
+
if (hasStoredTokens) {
|
|
211253
|
+
console.log(`Stored OAuth token for SSE server '${mcpServerName}' was rejected. Please re-authenticate using: /mcp auth ${mcpServerName}`);
|
|
211254
|
+
} else {
|
|
211255
|
+
console.log(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. Please authenticate using: /mcp auth ${mcpServerName}`);
|
|
211256
|
+
}
|
|
211257
|
+
}
|
|
211258
|
+
throw new Error(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. Please authenticate using: /mcp auth ${mcpServerName}`);
|
|
211259
|
+
}
|
|
211260
|
+
console.log(`\u{1F50D} Attempting OAuth discovery for '${mcpServerName}'...`);
|
|
211261
|
+
if (hasNetworkTransport(mcpServerConfig)) {
|
|
211262
|
+
const serverUrl = new URL(mcpServerConfig.httpUrl || mcpServerConfig.url);
|
|
211263
|
+
const baseUrl = `${serverUrl.protocol}//${serverUrl.host}`;
|
|
211264
|
+
try {
|
|
211265
|
+
const oauthConfig = await OAuthUtils.discoverOAuthConfig(baseUrl);
|
|
211266
|
+
if (oauthConfig) {
|
|
211267
|
+
console.log(`Discovered OAuth configuration from base URL for server '${mcpServerName}'`);
|
|
211268
|
+
const oauthAuthConfig = {
|
|
211269
|
+
enabled: true,
|
|
211270
|
+
authorizationUrl: oauthConfig.authorizationUrl,
|
|
211271
|
+
tokenUrl: oauthConfig.tokenUrl,
|
|
211272
|
+
scopes: oauthConfig.scopes || []
|
|
211273
|
+
};
|
|
211274
|
+
const authServerUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
|
|
211275
|
+
console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
|
|
211276
|
+
const authProvider = new MCPOAuthProvider(new MCPOAuthTokenStorage());
|
|
211277
|
+
await authProvider.authenticate(mcpServerName, oauthAuthConfig, authServerUrl);
|
|
211278
|
+
const tokenStorage = new MCPOAuthTokenStorage();
|
|
211279
|
+
const credentials = await tokenStorage.getCredentials(mcpServerName);
|
|
211280
|
+
if (credentials) {
|
|
211281
|
+
const authProvider2 = new MCPOAuthProvider(tokenStorage);
|
|
211282
|
+
const accessToken = await authProvider2.getValidToken(mcpServerName, {
|
|
211283
|
+
// Pass client ID if available
|
|
211284
|
+
clientId: credentials.clientId
|
|
211285
|
+
});
|
|
211286
|
+
if (accessToken) {
|
|
211287
|
+
const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
|
|
211288
|
+
if (oauthTransport) {
|
|
211289
|
+
try {
|
|
211290
|
+
await mcpClient.connect(oauthTransport, {
|
|
211291
|
+
timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC
|
|
211292
|
+
});
|
|
211293
|
+
return mcpClient;
|
|
211294
|
+
} catch (retryError) {
|
|
211295
|
+
console.error(`Failed to connect with OAuth token: ${getErrorMessage(retryError)}`);
|
|
211296
|
+
throw retryError;
|
|
211297
|
+
}
|
|
211298
|
+
} else {
|
|
211299
|
+
console.error(`Failed to create OAuth transport for server '${mcpServerName}'`);
|
|
211300
|
+
throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
|
|
211301
|
+
}
|
|
211302
|
+
} else {
|
|
211303
|
+
console.error(`Failed to get OAuth token for server '${mcpServerName}'`);
|
|
211304
|
+
throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
|
|
211305
|
+
}
|
|
211306
|
+
} else {
|
|
211307
|
+
console.error(`Failed to get stored credentials for server '${mcpServerName}'`);
|
|
211308
|
+
throw new Error(`Failed to get stored credentials for server '${mcpServerName}'`);
|
|
211309
|
+
}
|
|
211310
|
+
} else {
|
|
211311
|
+
console.error(`\u274C Could not configure OAuth for '${mcpServerName}' - please authenticate manually with /mcp auth ${mcpServerName}`);
|
|
211312
|
+
throw new Error(`OAuth configuration failed for '${mcpServerName}'. Please authenticate manually with /mcp auth ${mcpServerName}`);
|
|
211313
|
+
}
|
|
211314
|
+
} catch (discoveryError) {
|
|
211315
|
+
console.error(`\u274C OAuth discovery failed for '${mcpServerName}' - please authenticate manually with /mcp auth ${mcpServerName}`);
|
|
211316
|
+
throw discoveryError;
|
|
211317
|
+
}
|
|
211318
|
+
} else {
|
|
211319
|
+
console.error(`\u274C '${mcpServerName}' requires authentication but no OAuth configuration found`);
|
|
211320
|
+
throw new Error(`MCP server '${mcpServerName}' requires authentication. Please configure OAuth or check server settings.`);
|
|
211321
|
+
}
|
|
211322
|
+
}
|
|
211323
|
+
} else {
|
|
211324
|
+
const errorMessage = error2.message || String(error2);
|
|
211325
|
+
const isNetworkError = errorMessage.includes("ENOTFOUND") || errorMessage.includes("ECONNREFUSED");
|
|
211326
|
+
let conciseError;
|
|
211327
|
+
if (isNetworkError) {
|
|
211328
|
+
conciseError = `Cannot connect to '${mcpServerName}' - server may be down or URL incorrect`;
|
|
211329
|
+
} else {
|
|
211330
|
+
conciseError = `Connection failed for '${mcpServerName}': ${errorMessage}`;
|
|
211331
|
+
}
|
|
211332
|
+
if (process.env["SANDBOX"]) {
|
|
211333
|
+
conciseError += ` (check sandbox availability)`;
|
|
211334
|
+
}
|
|
211335
|
+
throw new Error(conciseError);
|
|
211336
|
+
}
|
|
211337
|
+
}
|
|
211338
|
+
}
|
|
211002
211339
|
async function createTransport(mcpServerName, mcpServerConfig, debugMode, sendSdkMcpMessage) {
|
|
211003
211340
|
if (isSdkMcpServerConfig(mcpServerConfig)) {
|
|
211004
211341
|
if (!sendSdkMcpMessage) {
|
|
@@ -211123,7 +211460,7 @@ function isEnabled(funcDecl, mcpServerName, mcpServerConfig) {
|
|
|
211123
211460
|
}
|
|
211124
211461
|
return !includeTools || includeTools.some((tool) => tool === funcDecl.name || tool.startsWith(`${funcDecl.name}(`));
|
|
211125
211462
|
}
|
|
211126
|
-
var import_shell_quote3, MCP_DEFAULT_TIMEOUT_MSEC, MCPServerStatus, MCPDiscoveryState, McpClient, serverStatuses, mcpDiscoveryState, statusChangeListeners;
|
|
211463
|
+
var import_shell_quote3, MCP_DEFAULT_TIMEOUT_MSEC, MCPServerStatus, MCPDiscoveryState, McpClient, serverStatuses, mcpDiscoveryState, mcpServerRequiresOAuth, statusChangeListeners;
|
|
211127
211464
|
var init_mcp_client = __esm({
|
|
211128
211465
|
"packages/core/dist/src/tools/mcp-client.js"() {
|
|
211129
211466
|
"use strict";
|
|
@@ -211255,15 +211592,6 @@ var init_mcp_client = __esm({
|
|
|
211255
211592
|
getStatus() {
|
|
211256
211593
|
return this.status;
|
|
211257
211594
|
}
|
|
211258
|
-
async readResource(uri, options2) {
|
|
211259
|
-
if (this.status !== MCPServerStatus.CONNECTED) {
|
|
211260
|
-
throw new Error("Client is not connected.");
|
|
211261
|
-
}
|
|
211262
|
-
if (this.client.getServerCapabilities()?.resources == null) {
|
|
211263
|
-
throw new Error("MCP server does not support resources.");
|
|
211264
|
-
}
|
|
211265
|
-
return this.client.request({ method: "resources/read", params: { uri } }, ReadResourceResultSchema, options2);
|
|
211266
|
-
}
|
|
211267
211595
|
updateStatus(status) {
|
|
211268
211596
|
this.status = status;
|
|
211269
211597
|
updateMCPServerStatus(this.serverName, status);
|
|
@@ -211280,14 +211608,21 @@ var init_mcp_client = __esm({
|
|
|
211280
211608
|
};
|
|
211281
211609
|
serverStatuses = /* @__PURE__ */ new Map();
|
|
211282
211610
|
mcpDiscoveryState = MCPDiscoveryState.NOT_STARTED;
|
|
211611
|
+
mcpServerRequiresOAuth = /* @__PURE__ */ new Map();
|
|
211283
211612
|
statusChangeListeners = [];
|
|
211284
211613
|
__name(updateMCPServerStatus, "updateMCPServerStatus");
|
|
211285
211614
|
__name(getMCPServerStatus, "getMCPServerStatus");
|
|
211286
211615
|
__name(getMCPDiscoveryState, "getMCPDiscoveryState");
|
|
211616
|
+
__name(extractWWWAuthenticateHeader, "extractWWWAuthenticateHeader");
|
|
211617
|
+
__name(handleAutomaticOAuth, "handleAutomaticOAuth");
|
|
211618
|
+
__name(createTransportWithOAuth, "createTransportWithOAuth");
|
|
211287
211619
|
__name(populateMcpServerCommand, "populateMcpServerCommand");
|
|
211620
|
+
__name(connectAndDiscover, "connectAndDiscover");
|
|
211288
211621
|
__name(discoverTools, "discoverTools");
|
|
211289
211622
|
__name(discoverPrompts, "discoverPrompts");
|
|
211290
211623
|
__name(invokeMcpPrompt, "invokeMcpPrompt");
|
|
211624
|
+
__name(hasNetworkTransport, "hasNetworkTransport");
|
|
211625
|
+
__name(connectToMcpServer, "connectToMcpServer");
|
|
211291
211626
|
__name(createTransport, "createTransport");
|
|
211292
211627
|
__name(isEnabled, "isEnabled");
|
|
211293
211628
|
}
|
|
@@ -211348,42 +211683,6 @@ var init_mcp_client_manager = __esm({
|
|
|
211348
211683
|
await Promise.all(discoveryPromises);
|
|
211349
211684
|
this.discoveryState = MCPDiscoveryState.COMPLETED;
|
|
211350
211685
|
}
|
|
211351
|
-
/**
|
|
211352
|
-
* Connects to a single MCP server and discovers its tools/prompts.
|
|
211353
|
-
* The connected client is tracked so it can be closed by {@link stop}.
|
|
211354
|
-
*
|
|
211355
|
-
* This is primarily used for on-demand re-discovery flows (e.g. after OAuth).
|
|
211356
|
-
*/
|
|
211357
|
-
async discoverMcpToolsForServer(serverName, cliConfig) {
|
|
211358
|
-
const servers = populateMcpServerCommand(this.cliConfig.getMcpServers() || {}, this.cliConfig.getMcpServerCommand());
|
|
211359
|
-
const serverConfig = servers[serverName];
|
|
211360
|
-
if (!serverConfig) {
|
|
211361
|
-
return;
|
|
211362
|
-
}
|
|
211363
|
-
const existingClient = this.clients.get(serverName);
|
|
211364
|
-
if (existingClient) {
|
|
211365
|
-
try {
|
|
211366
|
-
await existingClient.disconnect();
|
|
211367
|
-
} catch (error2) {
|
|
211368
|
-
console.error(`Error stopping client '${serverName}': ${getErrorMessage(error2)}`);
|
|
211369
|
-
} finally {
|
|
211370
|
-
this.clients.delete(serverName);
|
|
211371
|
-
this.eventEmitter?.emit("mcp-client-update", this.clients);
|
|
211372
|
-
}
|
|
211373
|
-
}
|
|
211374
|
-
const sdkCallback = isSdkMcpServerConfig(serverConfig) ? this.sendSdkMcpMessage : void 0;
|
|
211375
|
-
const client = new McpClient(serverName, serverConfig, this.toolRegistry, this.cliConfig.getPromptRegistry(), this.cliConfig.getWorkspaceContext(), this.cliConfig.getDebugMode(), sdkCallback);
|
|
211376
|
-
this.clients.set(serverName, client);
|
|
211377
|
-
this.eventEmitter?.emit("mcp-client-update", this.clients);
|
|
211378
|
-
try {
|
|
211379
|
-
await client.connect();
|
|
211380
|
-
await client.discover(cliConfig);
|
|
211381
|
-
} catch (error2) {
|
|
211382
|
-
console.error(`Error during discovery for server '${serverName}': ${getErrorMessage(error2)}`);
|
|
211383
|
-
} finally {
|
|
211384
|
-
this.eventEmitter?.emit("mcp-client-update", this.clients);
|
|
211385
|
-
}
|
|
211386
|
-
}
|
|
211387
211686
|
/**
|
|
211388
211687
|
* Stops all running local MCP servers and closes all client connections.
|
|
211389
211688
|
* This is the cleanup method to be called on application exit.
|
|
@@ -211402,24 +211701,6 @@ var init_mcp_client_manager = __esm({
|
|
|
211402
211701
|
getDiscoveryState() {
|
|
211403
211702
|
return this.discoveryState;
|
|
211404
211703
|
}
|
|
211405
|
-
async readResource(serverName, uri, options2) {
|
|
211406
|
-
let client = this.clients.get(serverName);
|
|
211407
|
-
if (!client) {
|
|
211408
|
-
const servers = populateMcpServerCommand(this.cliConfig.getMcpServers() || {}, this.cliConfig.getMcpServerCommand());
|
|
211409
|
-
const serverConfig = servers[serverName];
|
|
211410
|
-
if (!serverConfig) {
|
|
211411
|
-
throw new Error(`MCP server '${serverName}' is not configured.`);
|
|
211412
|
-
}
|
|
211413
|
-
const sdkCallback = isSdkMcpServerConfig(serverConfig) ? this.sendSdkMcpMessage : void 0;
|
|
211414
|
-
client = new McpClient(serverName, serverConfig, this.toolRegistry, this.cliConfig.getPromptRegistry(), this.cliConfig.getWorkspaceContext(), this.cliConfig.getDebugMode(), sdkCallback);
|
|
211415
|
-
this.clients.set(serverName, client);
|
|
211416
|
-
this.eventEmitter?.emit("mcp-client-update", this.clients);
|
|
211417
|
-
}
|
|
211418
|
-
if (client.getStatus() !== MCPServerStatus.CONNECTED) {
|
|
211419
|
-
await client.connect();
|
|
211420
|
-
}
|
|
211421
|
-
return client.readResource(uri, options2);
|
|
211422
|
-
}
|
|
211423
211704
|
};
|
|
211424
211705
|
}
|
|
211425
211706
|
});
|
|
@@ -211433,6 +211714,7 @@ var init_tool_registry = __esm({
|
|
|
211433
211714
|
"use strict";
|
|
211434
211715
|
init_esbuild_shims();
|
|
211435
211716
|
init_tools();
|
|
211717
|
+
init_mcp_client();
|
|
211436
211718
|
init_mcp_client_manager();
|
|
211437
211719
|
init_mcp_tool();
|
|
211438
211720
|
import_shell_quote4 = __toESM(require_shell_quote(), 1);
|
|
@@ -211641,7 +211923,11 @@ Signal: Signal number or \`(none)\` if no signal was received.
|
|
|
211641
211923
|
}
|
|
211642
211924
|
}
|
|
211643
211925
|
this.config.getPromptRegistry().removePromptsByServer(serverName);
|
|
211644
|
-
|
|
211926
|
+
const mcpServers = this.config.getMcpServers() ?? {};
|
|
211927
|
+
const serverConfig = mcpServers[serverName];
|
|
211928
|
+
if (serverConfig) {
|
|
211929
|
+
await connectAndDiscover(serverName, serverConfig, this, this.config.getPromptRegistry(), this.config.getDebugMode(), this.config.getWorkspaceContext(), this.config);
|
|
211930
|
+
}
|
|
211645
211931
|
}
|
|
211646
211932
|
async discoverAndRegisterToolsFromCommand() {
|
|
211647
211933
|
const discoveryCmd = this.config.getToolDiscoveryCommand();
|
|
@@ -211788,23 +212074,6 @@ Signal: Signal number or \`(none)\` if no signal was received.
|
|
|
211788
212074
|
getTool(name3) {
|
|
211789
212075
|
return this.tools.get(name3);
|
|
211790
212076
|
}
|
|
211791
|
-
async readMcpResource(serverName, uri, options2) {
|
|
211792
|
-
if (!this.config.isTrustedFolder()) {
|
|
211793
|
-
throw new Error("MCP resources are unavailable in untrusted folders.");
|
|
211794
|
-
}
|
|
211795
|
-
return this.mcpClientManager.readResource(serverName, uri, options2);
|
|
211796
|
-
}
|
|
211797
|
-
/**
|
|
211798
|
-
* Stops all MCP clients and cleans up resources.
|
|
211799
|
-
* This method is idempotent and safe to call multiple times.
|
|
211800
|
-
*/
|
|
211801
|
-
async stop() {
|
|
211802
|
-
try {
|
|
211803
|
-
await this.mcpClientManager.stop();
|
|
211804
|
-
} catch (error2) {
|
|
211805
|
-
console.error("Error stopping MCP clients:", error2);
|
|
211806
|
-
}
|
|
211807
|
-
}
|
|
211808
212077
|
};
|
|
211809
212078
|
}
|
|
211810
212079
|
});
|
|
@@ -217429,7 +217698,7 @@ ${textContent2}
|
|
|
217429
217698
|
return `Fetching content from ${this.params.url} and processing with prompt: "${displayPrompt}"`;
|
|
217430
217699
|
}
|
|
217431
217700
|
async shouldConfirmExecute() {
|
|
217432
|
-
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT
|
|
217701
|
+
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT) {
|
|
217433
217702
|
return false;
|
|
217434
217703
|
}
|
|
217435
217704
|
const confirmationDetails = {
|
|
@@ -217820,7 +218089,7 @@ var init_web_search = __esm({
|
|
|
217820
218089
|
return ` (Searching the web via ${provider})`;
|
|
217821
218090
|
}
|
|
217822
218091
|
async shouldConfirmExecute(_abortSignal) {
|
|
217823
|
-
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT
|
|
218092
|
+
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT) {
|
|
217824
218093
|
return false;
|
|
217825
218094
|
}
|
|
217826
218095
|
const confirmationDetails = {
|
|
@@ -220828,8 +221097,8 @@ var init_esm21 = __esm({
|
|
|
220828
221097
|
}
|
|
220829
221098
|
return this._userIgnored(path123, stats);
|
|
220830
221099
|
}
|
|
220831
|
-
_isntIgnored(path123,
|
|
220832
|
-
return !this._isIgnored(path123,
|
|
221100
|
+
_isntIgnored(path123, stat10) {
|
|
221101
|
+
return !this._isIgnored(path123, stat10);
|
|
220833
221102
|
}
|
|
220834
221103
|
/**
|
|
220835
221104
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
@@ -221133,15 +221402,9 @@ async function loadSkillsFromDir(baseDir) {
|
|
|
221133
221402
|
return [];
|
|
221134
221403
|
}
|
|
221135
221404
|
}
|
|
221136
|
-
function normalizeSkillFileContent(content) {
|
|
221137
|
-
let normalized2 = content.replace(/^\uFEFF/, "");
|
|
221138
|
-
normalized2 = normalized2.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
221139
|
-
return normalized2;
|
|
221140
|
-
}
|
|
221141
221405
|
function parseSkillContent(content, filePath) {
|
|
221142
|
-
const
|
|
221143
|
-
const
|
|
221144
|
-
const match2 = normalizedContent.match(frontmatterRegex);
|
|
221406
|
+
const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
221407
|
+
const match2 = content.match(frontmatterRegex);
|
|
221145
221408
|
if (!match2) {
|
|
221146
221409
|
throw new Error("Invalid format: missing YAML frontmatter");
|
|
221147
221410
|
}
|
|
@@ -221222,7 +221485,6 @@ var init_skill_load = __esm({
|
|
|
221222
221485
|
init_yaml_parser();
|
|
221223
221486
|
SKILL_MANIFEST_FILE = "SKILL.md";
|
|
221224
221487
|
__name(loadSkillsFromDir, "loadSkillsFromDir");
|
|
221225
|
-
__name(normalizeSkillFileContent, "normalizeSkillFileContent");
|
|
221226
221488
|
__name(parseSkillContent, "parseSkillContent");
|
|
221227
221489
|
__name(validateConfig, "validateConfig");
|
|
221228
221490
|
}
|
|
@@ -221233,7 +221495,7 @@ import * as fs45 from "fs/promises";
|
|
|
221233
221495
|
import * as fsSync2 from "fs";
|
|
221234
221496
|
import * as path49 from "path";
|
|
221235
221497
|
import * as os19 from "os";
|
|
221236
|
-
function
|
|
221498
|
+
function normalizeSkillFileContent(content) {
|
|
221237
221499
|
let normalized2 = content.replace(/^\uFEFF/, "");
|
|
221238
221500
|
normalized2 = normalized2.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
221239
221501
|
return normalized2;
|
|
@@ -221445,7 +221707,7 @@ var init_skill_manager = __esm({
|
|
|
221445
221707
|
*/
|
|
221446
221708
|
parseSkillContent(content, filePath, level) {
|
|
221447
221709
|
try {
|
|
221448
|
-
const normalizedContent =
|
|
221710
|
+
const normalizedContent = normalizeSkillFileContent(content);
|
|
221449
221711
|
const frontmatterRegex = /^---\n([\s\S]*?)\n---(?:\n|$)([\s\S]*)$/;
|
|
221450
221712
|
const match2 = normalizedContent.match(frontmatterRegex);
|
|
221451
221713
|
if (!match2) {
|
|
@@ -221533,23 +221795,9 @@ var init_skill_manager = __esm({
|
|
|
221533
221795
|
const entries = await fs45.readdir(baseDir, { withFileTypes: true });
|
|
221534
221796
|
const skills = [];
|
|
221535
221797
|
for (const entry of entries) {
|
|
221536
|
-
|
|
221537
|
-
const isSymlink = entry.isSymbolicLink();
|
|
221538
|
-
if (!isDirectory && !isSymlink)
|
|
221798
|
+
if (!entry.isDirectory())
|
|
221539
221799
|
continue;
|
|
221540
221800
|
const skillDir = path49.join(baseDir, entry.name);
|
|
221541
|
-
if (isSymlink) {
|
|
221542
|
-
try {
|
|
221543
|
-
const targetStat = await fs45.stat(skillDir);
|
|
221544
|
-
if (!targetStat.isDirectory()) {
|
|
221545
|
-
console.warn(`Skipping symlink ${entry.name} that does not point to a directory`);
|
|
221546
|
-
continue;
|
|
221547
|
-
}
|
|
221548
|
-
} catch (error2) {
|
|
221549
|
-
console.warn(`Skipping invalid symlink ${entry.name}: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
|
|
221550
|
-
continue;
|
|
221551
|
-
}
|
|
221552
|
-
}
|
|
221553
221801
|
const skillManifest = path49.join(skillDir, SKILL_MANIFEST_FILE2);
|
|
221554
221802
|
try {
|
|
221555
221803
|
await fs45.access(skillManifest);
|
|
@@ -221637,7 +221885,7 @@ var init_skill_manager = __esm({
|
|
|
221637
221885
|
}
|
|
221638
221886
|
}
|
|
221639
221887
|
};
|
|
221640
|
-
__name(
|
|
221888
|
+
__name(normalizeSkillFileContent, "normalizeSkillFileContent");
|
|
221641
221889
|
}
|
|
221642
221890
|
});
|
|
221643
221891
|
|
|
@@ -224913,16 +225161,16 @@ var init_list = __esm({
|
|
|
224913
225161
|
let fd;
|
|
224914
225162
|
try {
|
|
224915
225163
|
fd = fs48.openSync(file, "r");
|
|
224916
|
-
const
|
|
225164
|
+
const stat10 = fs48.fstatSync(fd);
|
|
224917
225165
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
224918
|
-
if (
|
|
224919
|
-
const buf = Buffer.allocUnsafe(
|
|
224920
|
-
const read3 = fs48.readSync(fd, buf, 0,
|
|
225166
|
+
if (stat10.size < readSize) {
|
|
225167
|
+
const buf = Buffer.allocUnsafe(stat10.size);
|
|
225168
|
+
const read3 = fs48.readSync(fd, buf, 0, stat10.size, 0);
|
|
224921
225169
|
p2.end(read3 === buf.byteLength ? buf : buf.subarray(0, read3));
|
|
224922
225170
|
} else {
|
|
224923
225171
|
let pos2 = 0;
|
|
224924
225172
|
const buf = Buffer.allocUnsafe(readSize);
|
|
224925
|
-
while (pos2 <
|
|
225173
|
+
while (pos2 < stat10.size) {
|
|
224926
225174
|
const bytesRead = fs48.readSync(fd, buf, 0, readSize, pos2);
|
|
224927
225175
|
if (bytesRead === 0)
|
|
224928
225176
|
break;
|
|
@@ -224947,13 +225195,13 @@ var init_list = __esm({
|
|
|
224947
225195
|
const p2 = new Promise((resolve31, reject) => {
|
|
224948
225196
|
parse14.on("error", reject);
|
|
224949
225197
|
parse14.on("end", resolve31);
|
|
224950
|
-
fs48.stat(file, (er2,
|
|
225198
|
+
fs48.stat(file, (er2, stat10) => {
|
|
224951
225199
|
if (er2) {
|
|
224952
225200
|
reject(er2);
|
|
224953
225201
|
} else {
|
|
224954
225202
|
const stream2 = new ReadStream(file, {
|
|
224955
225203
|
readSize,
|
|
224956
|
-
size:
|
|
225204
|
+
size: stat10.size
|
|
224957
225205
|
});
|
|
224958
225206
|
stream2.on("error", reject);
|
|
224959
225207
|
stream2.pipe(parse14);
|
|
@@ -225169,21 +225417,21 @@ var init_write_entry = __esm({
|
|
|
225169
225417
|
return super.emit(ev, ...data);
|
|
225170
225418
|
}
|
|
225171
225419
|
[LSTAT]() {
|
|
225172
|
-
fs49.lstat(this.absolute, (er2,
|
|
225420
|
+
fs49.lstat(this.absolute, (er2, stat10) => {
|
|
225173
225421
|
if (er2) {
|
|
225174
225422
|
return this.emit("error", er2);
|
|
225175
225423
|
}
|
|
225176
|
-
this[ONLSTAT](
|
|
225424
|
+
this[ONLSTAT](stat10);
|
|
225177
225425
|
});
|
|
225178
225426
|
}
|
|
225179
|
-
[ONLSTAT](
|
|
225180
|
-
this.statCache.set(this.absolute,
|
|
225181
|
-
this.stat =
|
|
225182
|
-
if (!
|
|
225183
|
-
|
|
225427
|
+
[ONLSTAT](stat10) {
|
|
225428
|
+
this.statCache.set(this.absolute, stat10);
|
|
225429
|
+
this.stat = stat10;
|
|
225430
|
+
if (!stat10.isFile()) {
|
|
225431
|
+
stat10.size = 0;
|
|
225184
225432
|
}
|
|
225185
|
-
this.type = getType3(
|
|
225186
|
-
this.emit("stat",
|
|
225433
|
+
this.type = getType3(stat10);
|
|
225434
|
+
this.emit("stat", stat10);
|
|
225187
225435
|
this[PROCESS2]();
|
|
225188
225436
|
}
|
|
225189
225437
|
[PROCESS2]() {
|
|
@@ -225633,7 +225881,7 @@ var init_write_entry = __esm({
|
|
|
225633
225881
|
return this;
|
|
225634
225882
|
}
|
|
225635
225883
|
};
|
|
225636
|
-
getType3 = /* @__PURE__ */ __name((
|
|
225884
|
+
getType3 = /* @__PURE__ */ __name((stat10) => stat10.isFile() ? "File" : stat10.isDirectory() ? "Directory" : stat10.isSymbolicLink() ? "SymbolicLink" : "Unsupported", "getType");
|
|
225637
225885
|
}
|
|
225638
225886
|
});
|
|
225639
225887
|
|
|
@@ -226233,21 +226481,21 @@ var init_pack = __esm({
|
|
|
226233
226481
|
[STAT](job) {
|
|
226234
226482
|
job.pending = true;
|
|
226235
226483
|
this[JOBS] += 1;
|
|
226236
|
-
const
|
|
226237
|
-
fs50[
|
|
226484
|
+
const stat10 = this.follow ? "stat" : "lstat";
|
|
226485
|
+
fs50[stat10](job.absolute, (er2, stat11) => {
|
|
226238
226486
|
job.pending = false;
|
|
226239
226487
|
this[JOBS] -= 1;
|
|
226240
226488
|
if (er2) {
|
|
226241
226489
|
this.emit("error", er2);
|
|
226242
226490
|
} else {
|
|
226243
|
-
this[ONSTAT](job,
|
|
226491
|
+
this[ONSTAT](job, stat11);
|
|
226244
226492
|
}
|
|
226245
226493
|
});
|
|
226246
226494
|
}
|
|
226247
|
-
[ONSTAT](job,
|
|
226248
|
-
this.statCache.set(job.absolute,
|
|
226249
|
-
job.stat =
|
|
226250
|
-
if (!this.filter(job.path,
|
|
226495
|
+
[ONSTAT](job, stat10) {
|
|
226496
|
+
this.statCache.set(job.absolute, stat10);
|
|
226497
|
+
job.stat = stat10;
|
|
226498
|
+
if (!this.filter(job.path, stat10)) {
|
|
226251
226499
|
job.ignore = true;
|
|
226252
226500
|
}
|
|
226253
226501
|
this[PROCESS3]();
|
|
@@ -226429,8 +226677,8 @@ var init_pack = __esm({
|
|
|
226429
226677
|
resume() {
|
|
226430
226678
|
}
|
|
226431
226679
|
[STAT](job) {
|
|
226432
|
-
const
|
|
226433
|
-
this[ONSTAT](job, fs50[
|
|
226680
|
+
const stat10 = this.follow ? "statSync" : "lstatSync";
|
|
226681
|
+
this[ONSTAT](job, fs50[stat10](job.absolute));
|
|
226434
226682
|
}
|
|
226435
226683
|
[READDIR](job) {
|
|
226436
226684
|
this[ONREADDIR](job, fs50.readdirSync(job.absolute));
|
|
@@ -227730,11 +227978,11 @@ var init_extract = __esm({
|
|
|
227730
227978
|
extractFileSync = /* @__PURE__ */ __name((opt) => {
|
|
227731
227979
|
const u2 = new UnpackSync(opt);
|
|
227732
227980
|
const file = opt.file;
|
|
227733
|
-
const
|
|
227981
|
+
const stat10 = fs55.statSync(file);
|
|
227734
227982
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
227735
227983
|
const stream2 = new ReadStreamSync(file, {
|
|
227736
227984
|
readSize,
|
|
227737
|
-
size:
|
|
227985
|
+
size: stat10.size
|
|
227738
227986
|
});
|
|
227739
227987
|
stream2.pipe(u2);
|
|
227740
227988
|
}, "extractFileSync");
|
|
@@ -227745,13 +227993,13 @@ var init_extract = __esm({
|
|
|
227745
227993
|
const p2 = new Promise((resolve31, reject) => {
|
|
227746
227994
|
u2.on("error", reject);
|
|
227747
227995
|
u2.on("close", resolve31);
|
|
227748
|
-
fs55.stat(file, (er2,
|
|
227996
|
+
fs55.stat(file, (er2, stat10) => {
|
|
227749
227997
|
if (er2) {
|
|
227750
227998
|
reject(er2);
|
|
227751
227999
|
} else {
|
|
227752
228000
|
const stream2 = new ReadStream(file, {
|
|
227753
228001
|
readSize,
|
|
227754
|
-
size:
|
|
228002
|
+
size: stat10.size
|
|
227755
228003
|
});
|
|
227756
228004
|
stream2.on("error", reject);
|
|
227757
228005
|
stream2.pipe(u2);
|
|
@@ -227996,9 +228244,9 @@ var init_update = __esm({
|
|
|
227996
228244
|
if (!opt.mtimeCache) {
|
|
227997
228245
|
opt.mtimeCache = /* @__PURE__ */ new Map();
|
|
227998
228246
|
}
|
|
227999
|
-
opt.filter = filter4 ? (path123,
|
|
228000
|
-
((opt.mtimeCache?.get(path123) ??
|
|
228001
|
-
((opt.mtimeCache?.get(path123) ??
|
|
228247
|
+
opt.filter = filter4 ? (path123, stat10) => filter4(path123, stat10) && !/* c8 ignore start */
|
|
228248
|
+
((opt.mtimeCache?.get(path123) ?? stat10.mtime ?? 0) > (stat10.mtime ?? 0)) : (path123, stat10) => !/* c8 ignore start */
|
|
228249
|
+
((opt.mtimeCache?.get(path123) ?? stat10.mtime ?? 0) > (stat10.mtime ?? 0));
|
|
228002
228250
|
}, "mtimeFilter");
|
|
228003
228251
|
}
|
|
228004
228252
|
});
|
|
@@ -232675,8 +232923,8 @@ async function collectResources(resourcePaths, pluginRoot, destDir) {
|
|
|
232675
232923
|
console.warn(`Resource path not found: ${resolvedPath}`);
|
|
232676
232924
|
continue;
|
|
232677
232925
|
}
|
|
232678
|
-
const
|
|
232679
|
-
if (
|
|
232926
|
+
const stat10 = fs60.statSync(resolvedPath);
|
|
232927
|
+
if (stat10.isDirectory()) {
|
|
232680
232928
|
const dirName = path62.basename(resolvedPath);
|
|
232681
232929
|
const parentDir = path62.dirname(resolvedPath);
|
|
232682
232930
|
if (dirName === destFolderName && parentDir === pluginRoot) {
|
|
@@ -242784,6 +243032,12 @@ var init_config3 = __esm({
|
|
|
242784
243032
|
getSessionId() {
|
|
242785
243033
|
return this.sessionId;
|
|
242786
243034
|
}
|
|
243035
|
+
/**
|
|
243036
|
+
* Releases resources owned by the config instance.
|
|
243037
|
+
*/
|
|
243038
|
+
async shutdown() {
|
|
243039
|
+
this.skillManager?.stopWatching();
|
|
243040
|
+
}
|
|
242787
243041
|
/**
|
|
242788
243042
|
* Starts a new session and resets session-scoped services.
|
|
242789
243043
|
*/
|
|
@@ -242918,24 +243172,6 @@ var init_config3 = __esm({
|
|
|
242918
243172
|
getToolRegistry() {
|
|
242919
243173
|
return this.toolRegistry;
|
|
242920
243174
|
}
|
|
242921
|
-
/**
|
|
242922
|
-
* Shuts down the Config and releases all resources.
|
|
242923
|
-
* This method is idempotent and safe to call multiple times.
|
|
242924
|
-
* It handles the case where initialization was not completed.
|
|
242925
|
-
*/
|
|
242926
|
-
async shutdown() {
|
|
242927
|
-
if (!this.initialized) {
|
|
242928
|
-
return;
|
|
242929
|
-
}
|
|
242930
|
-
try {
|
|
242931
|
-
this.skillManager?.stopWatching();
|
|
242932
|
-
if (this.toolRegistry) {
|
|
242933
|
-
await this.toolRegistry.stop();
|
|
242934
|
-
}
|
|
242935
|
-
} catch (error2) {
|
|
242936
|
-
console.error("Error during Config shutdown:", error2);
|
|
242937
|
-
}
|
|
242938
|
-
}
|
|
242939
243175
|
getPromptRegistry() {
|
|
242940
243176
|
return this.promptRegistry;
|
|
242941
243177
|
}
|
|
@@ -245681,12 +245917,12 @@ var require_resolve_symlink = __commonJS({
|
|
|
245681
245917
|
fs_1.default.realpath(path123, (error2, resolvedPath) => {
|
|
245682
245918
|
if (error2)
|
|
245683
245919
|
return queue.dequeue(suppressErrors ? null : error2, state);
|
|
245684
|
-
fs_1.default.stat(resolvedPath, (error3,
|
|
245920
|
+
fs_1.default.stat(resolvedPath, (error3, stat10) => {
|
|
245685
245921
|
if (error3)
|
|
245686
245922
|
return queue.dequeue(suppressErrors ? null : error3, state);
|
|
245687
|
-
if (
|
|
245923
|
+
if (stat10.isDirectory() && isRecursive(path123, resolvedPath, state))
|
|
245688
245924
|
return queue.dequeue(null, state);
|
|
245689
|
-
callback(
|
|
245925
|
+
callback(stat10, resolvedPath);
|
|
245690
245926
|
queue.dequeue(null, state);
|
|
245691
245927
|
});
|
|
245692
245928
|
});
|
|
@@ -245696,10 +245932,10 @@ var require_resolve_symlink = __commonJS({
|
|
|
245696
245932
|
queue.enqueue();
|
|
245697
245933
|
try {
|
|
245698
245934
|
const resolvedPath = fs_1.default.realpathSync(path123);
|
|
245699
|
-
const
|
|
245700
|
-
if (
|
|
245935
|
+
const stat10 = fs_1.default.statSync(resolvedPath);
|
|
245936
|
+
if (stat10.isDirectory() && isRecursive(path123, resolvedPath, state))
|
|
245701
245937
|
return;
|
|
245702
|
-
callback(
|
|
245938
|
+
callback(stat10, resolvedPath);
|
|
245703
245939
|
} catch (e4) {
|
|
245704
245940
|
if (!suppressErrors)
|
|
245705
245941
|
throw e4;
|
|
@@ -246018,8 +246254,8 @@ var require_walker = __commonJS({
|
|
|
246018
246254
|
this.walkDirectory(this.state, path123, path123, depth - 1, this.walk);
|
|
246019
246255
|
} else if (this.resolveSymlink && entry.isSymbolicLink()) {
|
|
246020
246256
|
let path123 = joinPath.joinPathWithBasePath(entry.name, directoryPath);
|
|
246021
|
-
this.resolveSymlink(path123, this.state, (
|
|
246022
|
-
if (
|
|
246257
|
+
this.resolveSymlink(path123, this.state, (stat10, resolvedPath) => {
|
|
246258
|
+
if (stat10.isDirectory()) {
|
|
246023
246259
|
resolvedPath = (0, utils_1.normalizePath)(resolvedPath, this.state.options);
|
|
246024
246260
|
if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path123 + pathSeparator))
|
|
246025
246261
|
return;
|
|
@@ -247947,7 +248183,7 @@ var init_skills = __esm({
|
|
|
247947
248183
|
import * as fs70 from "node:fs";
|
|
247948
248184
|
import * as path75 from "node:path";
|
|
247949
248185
|
import * as https5 from "node:https";
|
|
247950
|
-
import { stat as
|
|
248186
|
+
import { stat as stat6 } from "node:fs/promises";
|
|
247951
248187
|
function parseSourceAndPluginName(source2) {
|
|
247952
248188
|
const urlSchemes = ["http://", "https://", "git@", "sso://"];
|
|
247953
248189
|
let repoEndIndex = source2.length;
|
|
@@ -248072,7 +248308,7 @@ async function parseInstallSource(source2) {
|
|
|
248072
248308
|
}
|
|
248073
248309
|
} else {
|
|
248074
248310
|
try {
|
|
248075
|
-
await
|
|
248311
|
+
await stat6(repo);
|
|
248076
248312
|
installMetadata = {
|
|
248077
248313
|
source: repo,
|
|
248078
248314
|
type: "local",
|
|
@@ -373092,7 +373328,7 @@ __name(getPackageJson, "getPackageJson");
|
|
|
373092
373328
|
// packages/cli/src/utils/version.ts
|
|
373093
373329
|
async function getCliVersion() {
|
|
373094
373330
|
const pkgJson = await getPackageJson();
|
|
373095
|
-
return "0.9.0
|
|
373331
|
+
return "0.9.0";
|
|
373096
373332
|
}
|
|
373097
373333
|
__name(getCliVersion, "getCliVersion");
|
|
373098
373334
|
|
|
@@ -380628,7 +380864,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
|
|
|
380628
380864
|
|
|
380629
380865
|
// packages/cli/src/generated/git-commit.ts
|
|
380630
380866
|
init_esbuild_shims();
|
|
380631
|
-
var GIT_COMMIT_INFO2 = "
|
|
380867
|
+
var GIT_COMMIT_INFO2 = "91997c79";
|
|
380632
380868
|
|
|
380633
380869
|
// packages/cli/src/utils/systemInfo.ts
|
|
380634
380870
|
async function getNpmVersion() {
|
|
@@ -387071,161 +387307,6 @@ function parseAllAtCommands(query) {
|
|
|
387071
387307
|
);
|
|
387072
387308
|
}
|
|
387073
387309
|
__name(parseAllAtCommands, "parseAllAtCommands");
|
|
387074
|
-
function getConfiguredMcpServerNames(config2) {
|
|
387075
|
-
const names = new Set(Object.keys(config2.getMcpServers() ?? {}));
|
|
387076
|
-
if (config2.getMcpServerCommand()) {
|
|
387077
|
-
names.add("mcp");
|
|
387078
|
-
}
|
|
387079
|
-
return names;
|
|
387080
|
-
}
|
|
387081
|
-
__name(getConfiguredMcpServerNames, "getConfiguredMcpServerNames");
|
|
387082
|
-
function normalizeMcpResourceUri(serverName, resource) {
|
|
387083
|
-
if (resource.includes("://")) {
|
|
387084
|
-
return resource;
|
|
387085
|
-
}
|
|
387086
|
-
const cleaned = resource.startsWith("/") ? resource.slice(1) : resource;
|
|
387087
|
-
return `${serverName}://${cleaned}`;
|
|
387088
|
-
}
|
|
387089
|
-
__name(normalizeMcpResourceUri, "normalizeMcpResourceUri");
|
|
387090
|
-
function splitLeadingToken(text) {
|
|
387091
|
-
let i3 = 0;
|
|
387092
|
-
while (i3 < text.length && /\s/.test(text[i3])) {
|
|
387093
|
-
i3++;
|
|
387094
|
-
}
|
|
387095
|
-
if (i3 >= text.length) {
|
|
387096
|
-
return null;
|
|
387097
|
-
}
|
|
387098
|
-
let token2 = "";
|
|
387099
|
-
let inEscape = false;
|
|
387100
|
-
while (i3 < text.length) {
|
|
387101
|
-
const char = text[i3];
|
|
387102
|
-
if (inEscape) {
|
|
387103
|
-
token2 += char;
|
|
387104
|
-
inEscape = false;
|
|
387105
|
-
i3++;
|
|
387106
|
-
continue;
|
|
387107
|
-
}
|
|
387108
|
-
if (char === "\\") {
|
|
387109
|
-
inEscape = true;
|
|
387110
|
-
i3++;
|
|
387111
|
-
continue;
|
|
387112
|
-
}
|
|
387113
|
-
if (/[,\s;!?()[\]{}]/.test(char)) {
|
|
387114
|
-
break;
|
|
387115
|
-
}
|
|
387116
|
-
if (char === ".") {
|
|
387117
|
-
const nextChar = i3 + 1 < text.length ? text[i3 + 1] : "";
|
|
387118
|
-
if (nextChar === "" || /\s/.test(nextChar)) {
|
|
387119
|
-
break;
|
|
387120
|
-
}
|
|
387121
|
-
}
|
|
387122
|
-
token2 += char;
|
|
387123
|
-
i3++;
|
|
387124
|
-
}
|
|
387125
|
-
if (!token2) {
|
|
387126
|
-
return null;
|
|
387127
|
-
}
|
|
387128
|
-
return { token: token2, rest: text.slice(i3) };
|
|
387129
|
-
}
|
|
387130
|
-
__name(splitLeadingToken, "splitLeadingToken");
|
|
387131
|
-
function extractMcpResourceAtReferences(parts, config2) {
|
|
387132
|
-
const configuredServers = getConfiguredMcpServerNames(config2);
|
|
387133
|
-
const refs = [];
|
|
387134
|
-
const merged = [];
|
|
387135
|
-
for (let i3 = 0; i3 < parts.length; i3++) {
|
|
387136
|
-
const part = parts[i3];
|
|
387137
|
-
if (part.type !== "atPath") {
|
|
387138
|
-
merged.push(part);
|
|
387139
|
-
continue;
|
|
387140
|
-
}
|
|
387141
|
-
const atText = part.content;
|
|
387142
|
-
const colonIndex = atText.indexOf(":");
|
|
387143
|
-
if (!atText.startsWith("@") || colonIndex <= 1) {
|
|
387144
|
-
merged.push(part);
|
|
387145
|
-
continue;
|
|
387146
|
-
}
|
|
387147
|
-
const serverName = atText.slice(1, colonIndex);
|
|
387148
|
-
if (!configuredServers.has(serverName)) {
|
|
387149
|
-
merged.push(part);
|
|
387150
|
-
continue;
|
|
387151
|
-
}
|
|
387152
|
-
let resource = atText.slice(colonIndex + 1);
|
|
387153
|
-
if (!resource) {
|
|
387154
|
-
const next = parts[i3 + 1];
|
|
387155
|
-
if (next?.type === "text") {
|
|
387156
|
-
const tokenInfo = splitLeadingToken(next.content);
|
|
387157
|
-
if (tokenInfo) {
|
|
387158
|
-
resource = tokenInfo.token;
|
|
387159
|
-
const remainingText = tokenInfo.rest;
|
|
387160
|
-
parts[i3 + 1] = { type: "text", content: remainingText };
|
|
387161
|
-
}
|
|
387162
|
-
}
|
|
387163
|
-
}
|
|
387164
|
-
if (!resource) {
|
|
387165
|
-
merged.push({ type: "text", content: atText });
|
|
387166
|
-
continue;
|
|
387167
|
-
}
|
|
387168
|
-
const normalizedResource = resource.includes("://") ? resource : resource.startsWith("/") ? resource.slice(1) : resource;
|
|
387169
|
-
const normalizedAtCommand = `@${serverName}:${normalizedResource}`;
|
|
387170
|
-
refs.push({
|
|
387171
|
-
atCommand: normalizedAtCommand,
|
|
387172
|
-
serverName,
|
|
387173
|
-
uri: normalizeMcpResourceUri(serverName, normalizedResource)
|
|
387174
|
-
});
|
|
387175
|
-
merged.push({ type: "atPath", content: normalizedAtCommand });
|
|
387176
|
-
}
|
|
387177
|
-
return {
|
|
387178
|
-
parts: merged.filter(
|
|
387179
|
-
(p2) => !(p2.type === "text" && p2.content.trim() === "")
|
|
387180
|
-
),
|
|
387181
|
-
refs
|
|
387182
|
-
};
|
|
387183
|
-
}
|
|
387184
|
-
__name(extractMcpResourceAtReferences, "extractMcpResourceAtReferences");
|
|
387185
|
-
function formatMcpResourceContents(raw2, limits) {
|
|
387186
|
-
if (!raw2 || typeof raw2 !== "object") {
|
|
387187
|
-
return "[Error: Invalid MCP resource response]";
|
|
387188
|
-
}
|
|
387189
|
-
const contents = raw2.contents;
|
|
387190
|
-
if (!Array.isArray(contents)) {
|
|
387191
|
-
return "[Error: Invalid MCP resource response]";
|
|
387192
|
-
}
|
|
387193
|
-
const parts = [];
|
|
387194
|
-
for (const item of contents) {
|
|
387195
|
-
if (!item || typeof item !== "object") {
|
|
387196
|
-
continue;
|
|
387197
|
-
}
|
|
387198
|
-
const text = item.text;
|
|
387199
|
-
const blob = item.blob;
|
|
387200
|
-
const mimeType = item.mimeType;
|
|
387201
|
-
if (typeof text === "string") {
|
|
387202
|
-
parts.push(text);
|
|
387203
|
-
continue;
|
|
387204
|
-
}
|
|
387205
|
-
if (typeof blob === "string") {
|
|
387206
|
-
const mimeTypeLabel = typeof mimeType === "string" ? mimeType : "application/octet-stream";
|
|
387207
|
-
parts.push(
|
|
387208
|
-
`[Binary MCP resource omitted (mimeType: ${mimeTypeLabel}, bytes: ${blob.length})]`
|
|
387209
|
-
);
|
|
387210
|
-
}
|
|
387211
|
-
}
|
|
387212
|
-
let combined = parts.join("\n\n");
|
|
387213
|
-
const maxLines = limits.maxLinesPerResource;
|
|
387214
|
-
if (Number.isFinite(maxLines)) {
|
|
387215
|
-
const lines = combined.split("\n");
|
|
387216
|
-
if (lines.length > maxLines) {
|
|
387217
|
-
combined = `${lines.slice(0, maxLines).join("\n")}
|
|
387218
|
-
[truncated]`;
|
|
387219
|
-
}
|
|
387220
|
-
}
|
|
387221
|
-
const maxChars = limits.maxCharsPerResource;
|
|
387222
|
-
if (Number.isFinite(maxChars) && combined.length > maxChars) {
|
|
387223
|
-
combined = `${combined.slice(0, maxChars)}
|
|
387224
|
-
[truncated]`;
|
|
387225
|
-
}
|
|
387226
|
-
return combined;
|
|
387227
|
-
}
|
|
387228
|
-
__name(formatMcpResourceContents, "formatMcpResourceContents");
|
|
387229
387310
|
async function handleAtCommand({
|
|
387230
387311
|
query,
|
|
387231
387312
|
config: config2,
|
|
@@ -387234,15 +387315,10 @@ async function handleAtCommand({
|
|
|
387234
387315
|
messageId: userMessageTimestamp,
|
|
387235
387316
|
signal
|
|
387236
387317
|
}) {
|
|
387237
|
-
const
|
|
387238
|
-
const { parts: commandParts, refs: mcpResourceRefs } = extractMcpResourceAtReferences(parsedParts, config2);
|
|
387239
|
-
const mcpAtCommands = new Set(mcpResourceRefs.map((r5) => r5.atCommand));
|
|
387318
|
+
const commandParts = parseAllAtCommands(query);
|
|
387240
387319
|
const atPathCommandParts = commandParts.filter(
|
|
387241
387320
|
(part) => part.type === "atPath"
|
|
387242
387321
|
);
|
|
387243
|
-
const fileAtPathCommandParts = atPathCommandParts.filter(
|
|
387244
|
-
(part) => !mcpAtCommands.has(part.content)
|
|
387245
|
-
);
|
|
387246
387322
|
if (atPathCommandParts.length === 0) {
|
|
387247
387323
|
return { processedQuery: [{ text: query }], shouldProceed: true };
|
|
387248
387324
|
}
|
|
@@ -387259,7 +387335,14 @@ async function handleAtCommand({
|
|
|
387259
387335
|
const toolRegistry = config2.getToolRegistry();
|
|
387260
387336
|
const readManyFilesTool = toolRegistry.getTool("read_many_files");
|
|
387261
387337
|
const globTool = toolRegistry.getTool("glob");
|
|
387262
|
-
|
|
387338
|
+
if (!readManyFilesTool) {
|
|
387339
|
+
addItem(
|
|
387340
|
+
{ type: "error", text: "Error: read_many_files tool not found." },
|
|
387341
|
+
userMessageTimestamp
|
|
387342
|
+
);
|
|
387343
|
+
return { processedQuery: null, shouldProceed: false };
|
|
387344
|
+
}
|
|
387345
|
+
for (const atPathPart of atPathCommandParts) {
|
|
387263
387346
|
const originalAtPath = atPathPart.content;
|
|
387264
387347
|
if (originalAtPath === "@") {
|
|
387265
387348
|
onDebugMessage(
|
|
@@ -387419,7 +387502,7 @@ ${messages.join("\n")}`;
|
|
|
387419
387502
|
console.log(message);
|
|
387420
387503
|
onDebugMessage(message);
|
|
387421
387504
|
}
|
|
387422
|
-
if (pathSpecsToRead.length === 0
|
|
387505
|
+
if (pathSpecsToRead.length === 0) {
|
|
387423
387506
|
onDebugMessage("No valid file paths found in @ commands to read.");
|
|
387424
387507
|
if (initialQueryText === "@" && query.trim() === "@") {
|
|
387425
387508
|
return { processedQuery: [{ text: query }], shouldProceed: true };
|
|
@@ -387432,146 +387515,76 @@ ${messages.join("\n")}`;
|
|
|
387432
387515
|
};
|
|
387433
387516
|
}
|
|
387434
387517
|
const processedQueryParts = [{ text: initialQueryText }];
|
|
387435
|
-
const
|
|
387436
|
-
|
|
387437
|
-
|
|
387438
|
-
|
|
387439
|
-
|
|
387440
|
-
userMessageTimestamp
|
|
387441
|
-
);
|
|
387442
|
-
return { processedQuery: null, shouldProceed: false };
|
|
387518
|
+
const toolArgs = {
|
|
387519
|
+
paths: pathSpecsToRead,
|
|
387520
|
+
file_filtering_options: {
|
|
387521
|
+
respect_git_ignore: respectFileIgnore.respectGitIgnore,
|
|
387522
|
+
respect_qwen_ignore: respectFileIgnore.respectQwenIgnore
|
|
387443
387523
|
}
|
|
387444
|
-
|
|
387445
|
-
|
|
387446
|
-
|
|
387447
|
-
|
|
387448
|
-
|
|
387449
|
-
|
|
387450
|
-
|
|
387451
|
-
|
|
387452
|
-
|
|
387453
|
-
|
|
387454
|
-
invocation
|
|
387455
|
-
|
|
387456
|
-
|
|
387457
|
-
|
|
387458
|
-
|
|
387459
|
-
|
|
387460
|
-
|
|
387461
|
-
|
|
387462
|
-
|
|
387524
|
+
// Use configuration setting
|
|
387525
|
+
};
|
|
387526
|
+
let toolCallDisplay;
|
|
387527
|
+
let invocation = void 0;
|
|
387528
|
+
try {
|
|
387529
|
+
invocation = readManyFilesTool.build(toolArgs);
|
|
387530
|
+
const result = await invocation.execute(signal);
|
|
387531
|
+
toolCallDisplay = {
|
|
387532
|
+
callId: `client-read-${userMessageTimestamp}`,
|
|
387533
|
+
name: readManyFilesTool.displayName,
|
|
387534
|
+
description: invocation.getDescription(),
|
|
387535
|
+
status: "Success" /* Success */,
|
|
387536
|
+
resultDisplay: result.returnDisplay || `Successfully read: ${contentLabelsForDisplay.join(", ")}`,
|
|
387537
|
+
confirmationDetails: void 0
|
|
387538
|
+
};
|
|
387539
|
+
if (Array.isArray(result.llmContent)) {
|
|
387540
|
+
const fileContentRegex = /^--- (.*?) ---\n\n([\s\S]*?)\n\n$/;
|
|
387541
|
+
processedQueryParts.push({
|
|
387542
|
+
text: "\n--- Content from referenced files ---"
|
|
387463
387543
|
});
|
|
387464
|
-
|
|
387465
|
-
|
|
387466
|
-
|
|
387467
|
-
|
|
387468
|
-
|
|
387469
|
-
|
|
387470
|
-
|
|
387471
|
-
|
|
387472
|
-
if (match2) {
|
|
387473
|
-
const filePathSpecInContent = match2[1];
|
|
387474
|
-
const fileActualContent = match2[2].trim();
|
|
387475
|
-
processedQueryParts.push({
|
|
387476
|
-
text: `
|
|
387544
|
+
for (const part of result.llmContent) {
|
|
387545
|
+
if (typeof part === "string") {
|
|
387546
|
+
const match2 = fileContentRegex.exec(part);
|
|
387547
|
+
if (match2) {
|
|
387548
|
+
const filePathSpecInContent = match2[1];
|
|
387549
|
+
const fileActualContent = match2[2].trim();
|
|
387550
|
+
processedQueryParts.push({
|
|
387551
|
+
text: `
|
|
387477
387552
|
Content from @${filePathSpecInContent}:
|
|
387478
387553
|
`
|
|
387479
|
-
|
|
387480
|
-
|
|
387481
|
-
} else {
|
|
387482
|
-
processedQueryParts.push({ text: part });
|
|
387483
|
-
}
|
|
387554
|
+
});
|
|
387555
|
+
processedQueryParts.push({ text: fileActualContent });
|
|
387484
387556
|
} else {
|
|
387485
|
-
processedQueryParts.push(part);
|
|
387557
|
+
processedQueryParts.push({ text: part });
|
|
387486
387558
|
}
|
|
387559
|
+
} else {
|
|
387560
|
+
processedQueryParts.push(part);
|
|
387487
387561
|
}
|
|
387488
|
-
} else {
|
|
387489
|
-
onDebugMessage(
|
|
387490
|
-
"read_many_files tool returned no content or empty content."
|
|
387491
|
-
);
|
|
387492
387562
|
}
|
|
387493
|
-
}
|
|
387494
|
-
|
|
387495
|
-
|
|
387496
|
-
name: readManyFilesTool.displayName,
|
|
387497
|
-
description: invocation?.getDescription() ?? "Error attempting to execute tool to read files",
|
|
387498
|
-
status: "Error" /* Error */,
|
|
387499
|
-
resultDisplay: `Error reading files (${contentLabelsForDisplay.join(", ")}): ${getErrorMessage(error2)}`,
|
|
387500
|
-
confirmationDetails: void 0
|
|
387501
|
-
});
|
|
387502
|
-
addItem(
|
|
387503
|
-
{ type: "tool_group", tools: toolDisplays },
|
|
387504
|
-
userMessageTimestamp
|
|
387563
|
+
} else {
|
|
387564
|
+
onDebugMessage(
|
|
387565
|
+
"read_many_files tool returned no content or empty content."
|
|
387505
387566
|
);
|
|
387506
|
-
return { processedQuery: null, shouldProceed: false };
|
|
387507
387567
|
}
|
|
387508
|
-
}
|
|
387509
|
-
if (mcpResourceRefs.length > 0) {
|
|
387510
|
-
const totalCharLimit = config2.getTruncateToolOutputThreshold();
|
|
387511
|
-
const totalLineLimit = config2.getTruncateToolOutputLines();
|
|
387512
|
-
const maxCharsPerResource = Number.isFinite(totalCharLimit) ? Math.floor(totalCharLimit / Math.max(1, mcpResourceRefs.length)) : Number.POSITIVE_INFINITY;
|
|
387513
|
-
const maxLinesPerResource = Number.isFinite(totalLineLimit) ? Math.floor(totalLineLimit / Math.max(1, mcpResourceRefs.length)) : Number.POSITIVE_INFINITY;
|
|
387514
|
-
processedQueryParts.push({
|
|
387515
|
-
text: "\n--- Content from referenced MCP resources ---"
|
|
387516
|
-
});
|
|
387517
|
-
for (let i3 = 0; i3 < mcpResourceRefs.length; i3++) {
|
|
387518
|
-
const ref = mcpResourceRefs[i3];
|
|
387519
|
-
let resourceResult;
|
|
387520
|
-
try {
|
|
387521
|
-
if (signal.aborted) {
|
|
387522
|
-
const error2 = new Error("MCP resource read aborted");
|
|
387523
|
-
error2.name = "AbortError";
|
|
387524
|
-
throw error2;
|
|
387525
|
-
}
|
|
387526
|
-
resourceResult = await toolRegistry.readMcpResource(
|
|
387527
|
-
ref.serverName,
|
|
387528
|
-
ref.uri,
|
|
387529
|
-
{ signal }
|
|
387530
|
-
);
|
|
387531
|
-
toolDisplays.push({
|
|
387532
|
-
callId: `client-mcp-resource-${userMessageTimestamp}-${i3}`,
|
|
387533
|
-
name: "McpResourceRead",
|
|
387534
|
-
description: `Read MCP resource ${ref.uri} (server: ${ref.serverName})`,
|
|
387535
|
-
status: "Success" /* Success */,
|
|
387536
|
-
resultDisplay: `Read: ${ref.uri}`,
|
|
387537
|
-
confirmationDetails: void 0
|
|
387538
|
-
});
|
|
387539
|
-
} catch (error2) {
|
|
387540
|
-
toolDisplays.push({
|
|
387541
|
-
callId: `client-mcp-resource-${userMessageTimestamp}-${i3}`,
|
|
387542
|
-
name: "McpResourceRead",
|
|
387543
|
-
description: `Read MCP resource ${ref.uri} (server: ${ref.serverName})`,
|
|
387544
|
-
status: "Error" /* Error */,
|
|
387545
|
-
resultDisplay: `Error reading MCP resource (${ref.uri}): ${getErrorMessage(error2)}`,
|
|
387546
|
-
confirmationDetails: void 0
|
|
387547
|
-
});
|
|
387548
|
-
addItem(
|
|
387549
|
-
{ type: "tool_group", tools: toolDisplays },
|
|
387550
|
-
userMessageTimestamp
|
|
387551
|
-
);
|
|
387552
|
-
return { processedQuery: null, shouldProceed: false };
|
|
387553
|
-
}
|
|
387554
|
-
processedQueryParts.push({
|
|
387555
|
-
text: `
|
|
387556
|
-
Content from ${ref.atCommand}:
|
|
387557
|
-
`
|
|
387558
|
-
});
|
|
387559
|
-
processedQueryParts.push({
|
|
387560
|
-
text: formatMcpResourceContents(resourceResult, {
|
|
387561
|
-
maxCharsPerResource,
|
|
387562
|
-
maxLinesPerResource
|
|
387563
|
-
})
|
|
387564
|
-
});
|
|
387565
|
-
}
|
|
387566
|
-
processedQueryParts.push({ text: "\n--- End of MCP resource content ---" });
|
|
387567
|
-
}
|
|
387568
|
-
if (toolDisplays.length > 0) {
|
|
387569
387568
|
addItem(
|
|
387570
|
-
{ type: "tool_group", tools:
|
|
387569
|
+
{ type: "tool_group", tools: [toolCallDisplay] },
|
|
387570
|
+
userMessageTimestamp
|
|
387571
|
+
);
|
|
387572
|
+
return { processedQuery: processedQueryParts, shouldProceed: true };
|
|
387573
|
+
} catch (error2) {
|
|
387574
|
+
toolCallDisplay = {
|
|
387575
|
+
callId: `client-read-${userMessageTimestamp}`,
|
|
387576
|
+
name: readManyFilesTool.displayName,
|
|
387577
|
+
description: invocation?.getDescription() ?? "Error attempting to execute tool to read files",
|
|
387578
|
+
status: "Error" /* Error */,
|
|
387579
|
+
resultDisplay: `Error reading files (${contentLabelsForDisplay.join(", ")}): ${getErrorMessage(error2)}`,
|
|
387580
|
+
confirmationDetails: void 0
|
|
387581
|
+
};
|
|
387582
|
+
addItem(
|
|
387583
|
+
{ type: "tool_group", tools: [toolCallDisplay] },
|
|
387571
387584
|
userMessageTimestamp
|
|
387572
387585
|
);
|
|
387586
|
+
return { processedQuery: null, shouldProceed: false };
|
|
387573
387587
|
}
|
|
387574
|
-
return { processedQuery: processedQueryParts, shouldProceed: true };
|
|
387575
387588
|
}
|
|
387576
387589
|
__name(handleAtCommand, "handleAtCommand");
|
|
387577
387590
|
|
|
@@ -434273,7 +434286,7 @@ var GeminiAgent = class {
|
|
|
434273
434286
|
name: APPROVAL_MODE_INFO[mode].name,
|
|
434274
434287
|
description: APPROVAL_MODE_INFO[mode].description
|
|
434275
434288
|
}));
|
|
434276
|
-
const version2 = "0.9.0
|
|
434289
|
+
const version2 = "0.9.0";
|
|
434277
434290
|
return {
|
|
434278
434291
|
protocolVersion: PROTOCOL_VERSION,
|
|
434279
434292
|
agentInfo: {
|