@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.
Files changed (2) hide show
  1. package/cli.js +525 -512
  2. 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((stat11) => fromBlob(stat11, path123, type)), "blobFrom");
26274
- fileFrom = /* @__PURE__ */ __name((path123, type) => stat(path123).then((stat11) => fromFile(stat11, path123, type)), "fileFrom");
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((stat11, path123, type = "") => new fetch_blob_default([new BlobDataItem({
26276
+ fromBlob = /* @__PURE__ */ __name((stat10, path123, type = "") => new fetch_blob_default([new BlobDataItem({
26277
26277
  path: path123,
26278
- size: stat11.size,
26279
- lastModified: stat11.mtimeMs,
26278
+ size: stat10.size,
26279
+ lastModified: stat10.mtimeMs,
26280
26280
  start: 0
26281
26281
  })], { type }), "fromBlob");
26282
- fromFile = /* @__PURE__ */ __name((stat11, path123, type = "") => new file_default([new BlobDataItem({
26282
+ fromFile = /* @__PURE__ */ __name((stat10, path123, type = "") => new file_default([new BlobDataItem({
26283
26283
  path: path123,
26284
- size: stat11.size,
26285
- lastModified: stat11.mtimeMs,
26284
+ size: stat10.size,
26285
+ lastModified: stat10.mtimeMs,
26286
26286
  start: 0
26287
- })], basename(path123), { type, lastModified: stat11.mtimeMs }), "fromFile");
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, stat11) {
123532
+ fs110.stat(file, function(err, stat10) {
123533
123533
  if (!err) {
123534
- return cb(null, stat11.isFile() || stat11.isFIFO());
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, stat11) {
123541
+ fs110.stat(dir, function(err, stat10) {
123542
123542
  if (!err) {
123543
- return cb(null, stat11.isDirectory());
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 stat11 = fs110.statSync(file, { throwIfNoEntry: false });
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 !!stat11 && (stat11.isFile() || stat11.isFIFO());
124044
+ return !!stat10 && (stat10.isFile() || stat10.isFIFO());
124045
124045
  }, "isFile");
124046
124046
  var defaultIsDir = /* @__PURE__ */ __name(function isDirectory(dir) {
124047
124047
  try {
124048
- var stat11 = fs110.statSync(dir, { throwIfNoEntry: false });
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 !!stat11 && stat11.isDirectory();
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 stat11 = moduleDetailsFromPath(filename);
124480
- if (stat11 === void 0) {
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 = stat11.name;
124485
- basedir = stat11.basedir;
124486
- const fullModuleName = resolveModuleName(stat11);
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(stat11) {
124551
- const normalizedPath = path123.sep !== "/" ? stat11.path.split(path123.sep).join("/") : stat11.path;
124552
- return path123.posix.join(stat11.name, normalizedPath).replace(normalize11, "");
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-preview.3";
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 stat11 = fs_1.statSync(path123);
187419
- if (stat11.isFile() && isFile3) {
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 (stat11.isDirectory() && isDirectory) {
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(stat11, path123, options2) {
203476
- if (!stat11.isSymbolicLink() && !stat11.isFile()) {
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, stat11) {
203484
- cb(er2, er2 ? false : checkStat(stat11, path123, options2));
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, stat11) {
203504
- cb(er2, er2 ? false : checkStat(stat11, options2));
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(stat11, options2) {
203513
- return stat11.isFile() && checkMode(stat11, options2);
203512
+ function checkStat(stat10, options2) {
203513
+ return stat10.isFile() && checkMode(stat10, options2);
203514
203514
  }
203515
203515
  __name(checkStat, "checkStat");
203516
- function checkMode(stat11, options2) {
203517
- var mod2 = stat11.mode;
203518
- var uid = stat11.uid;
203519
- var gid = stat11.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 stat11 = await fs32.promises.stat(fullPath);
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: stat11.mtimeMs, parsed };
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: stat11.mtimeMs, parsed: void 0 };
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
- await this.mcpClientManager.discoverMcpToolsForServer(serverName, this.config);
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 || this.config.getApprovalMode() === ApprovalMode.PLAN) {
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 || this.config.getApprovalMode() === ApprovalMode.PLAN) {
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, stat11) {
220832
- return !this._isIgnored(path123, stat11);
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 normalizedContent = normalizeSkillFileContent(content);
221143
- const frontmatterRegex = /^---\n([\s\S]*?)\n---(?:\n|$)([\s\S]*)$/;
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 normalizeSkillFileContent2(content) {
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 = normalizeSkillFileContent2(content);
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
- const isDirectory = entry.isDirectory();
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(normalizeSkillFileContent2, "normalizeSkillFileContent");
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 stat11 = fs48.fstatSync(fd);
225164
+ const stat10 = fs48.fstatSync(fd);
224917
225165
  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
224918
- if (stat11.size < readSize) {
224919
- const buf = Buffer.allocUnsafe(stat11.size);
224920
- const read3 = fs48.readSync(fd, buf, 0, stat11.size, 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 < stat11.size) {
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, stat11) => {
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: stat11.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, stat11) => {
225420
+ fs49.lstat(this.absolute, (er2, stat10) => {
225173
225421
  if (er2) {
225174
225422
  return this.emit("error", er2);
225175
225423
  }
225176
- this[ONLSTAT](stat11);
225424
+ this[ONLSTAT](stat10);
225177
225425
  });
225178
225426
  }
225179
- [ONLSTAT](stat11) {
225180
- this.statCache.set(this.absolute, stat11);
225181
- this.stat = stat11;
225182
- if (!stat11.isFile()) {
225183
- stat11.size = 0;
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(stat11);
225186
- this.emit("stat", stat11);
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((stat11) => stat11.isFile() ? "File" : stat11.isDirectory() ? "Directory" : stat11.isSymbolicLink() ? "SymbolicLink" : "Unsupported", "getType");
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 stat11 = this.follow ? "stat" : "lstat";
226237
- fs50[stat11](job.absolute, (er2, stat12) => {
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, stat12);
226491
+ this[ONSTAT](job, stat11);
226244
226492
  }
226245
226493
  });
226246
226494
  }
226247
- [ONSTAT](job, stat11) {
226248
- this.statCache.set(job.absolute, stat11);
226249
- job.stat = stat11;
226250
- if (!this.filter(job.path, stat11)) {
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 stat11 = this.follow ? "statSync" : "lstatSync";
226433
- this[ONSTAT](job, fs50[stat11](job.absolute));
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 stat11 = fs55.statSync(file);
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: stat11.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, stat11) => {
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: stat11.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, stat11) => filter4(path123, stat11) && !/* c8 ignore start */
228000
- ((opt.mtimeCache?.get(path123) ?? stat11.mtime ?? 0) > (stat11.mtime ?? 0)) : (path123, stat11) => !/* c8 ignore start */
228001
- ((opt.mtimeCache?.get(path123) ?? stat11.mtime ?? 0) > (stat11.mtime ?? 0));
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 stat11 = fs60.statSync(resolvedPath);
232679
- if (stat11.isDirectory()) {
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, stat11) => {
245920
+ fs_1.default.stat(resolvedPath, (error3, stat10) => {
245685
245921
  if (error3)
245686
245922
  return queue.dequeue(suppressErrors ? null : error3, state);
245687
- if (stat11.isDirectory() && isRecursive(path123, resolvedPath, state))
245923
+ if (stat10.isDirectory() && isRecursive(path123, resolvedPath, state))
245688
245924
  return queue.dequeue(null, state);
245689
- callback(stat11, resolvedPath);
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 stat11 = fs_1.default.statSync(resolvedPath);
245700
- if (stat11.isDirectory() && isRecursive(path123, resolvedPath, state))
245935
+ const stat10 = fs_1.default.statSync(resolvedPath);
245936
+ if (stat10.isDirectory() && isRecursive(path123, resolvedPath, state))
245701
245937
  return;
245702
- callback(stat11, resolvedPath);
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, (stat11, resolvedPath) => {
246022
- if (stat11.isDirectory()) {
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 stat7 } from "node:fs/promises";
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 stat7(repo);
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-preview.3";
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 = "365cfbdd";
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 parsedParts = parseAllAtCommands(query);
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
- for (const atPathPart of fileAtPathCommandParts) {
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 && mcpResourceRefs.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 toolDisplays = [];
387436
- if (pathSpecsToRead.length > 0) {
387437
- if (!readManyFilesTool) {
387438
- addItem(
387439
- { type: "error", text: "Error: read_many_files tool not found." },
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
- const toolArgs = {
387445
- paths: pathSpecsToRead,
387446
- file_filtering_options: {
387447
- respect_git_ignore: respectFileIgnore.respectGitIgnore,
387448
- respect_qwen_ignore: respectFileIgnore.respectQwenIgnore
387449
- }
387450
- // Use configuration setting
387451
- };
387452
- let invocation = void 0;
387453
- try {
387454
- invocation = readManyFilesTool.build(toolArgs);
387455
- const result = await invocation.execute(signal);
387456
- toolDisplays.push({
387457
- callId: `client-read-${userMessageTimestamp}`,
387458
- name: readManyFilesTool.displayName,
387459
- description: invocation.getDescription(),
387460
- status: "Success" /* Success */,
387461
- resultDisplay: result.returnDisplay || `Successfully read: ${contentLabelsForDisplay.join(", ")}`,
387462
- confirmationDetails: void 0
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
- if (Array.isArray(result.llmContent)) {
387465
- const fileContentRegex = /^--- (.*?) ---\n\n([\s\S]*?)\n\n$/;
387466
- processedQueryParts.push({
387467
- text: "\n--- Content from referenced files ---"
387468
- });
387469
- for (const part of result.llmContent) {
387470
- if (typeof part === "string") {
387471
- const match2 = fileContentRegex.exec(part);
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
- processedQueryParts.push({ text: fileActualContent });
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
- } catch (error2) {
387494
- toolDisplays.push({
387495
- callId: `client-read-${userMessageTimestamp}`,
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: toolDisplays },
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-preview.3";
434289
+ const version2 = "0.9.0";
434277
434290
  return {
434278
434291
  protocolVersion: PROTOCOL_VERSION,
434279
434292
  agentInfo: {