@rdmind/rdmind 0.2.3-alpha.2 → 0.2.3-alpha.4

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 +1388 -190
  2. package/package.json +2 -2
package/cli.js CHANGED
@@ -26301,21 +26301,21 @@ var init_from = __esm({
26301
26301
  init_fetch_blob();
26302
26302
  ({ stat } = fs2);
26303
26303
  blobFromSync = /* @__PURE__ */ __name((path134, type) => fromBlob(statSync(path134), path134, type), "blobFromSync");
26304
- blobFrom = /* @__PURE__ */ __name((path134, type) => stat(path134).then((stat10) => fromBlob(stat10, path134, type)), "blobFrom");
26305
- fileFrom = /* @__PURE__ */ __name((path134, type) => stat(path134).then((stat10) => fromFile(stat10, path134, type)), "fileFrom");
26304
+ blobFrom = /* @__PURE__ */ __name((path134, type) => stat(path134).then((stat11) => fromBlob(stat11, path134, type)), "blobFrom");
26305
+ fileFrom = /* @__PURE__ */ __name((path134, type) => stat(path134).then((stat11) => fromFile(stat11, path134, type)), "fileFrom");
26306
26306
  fileFromSync = /* @__PURE__ */ __name((path134, type) => fromFile(statSync(path134), path134, type), "fileFromSync");
26307
- fromBlob = /* @__PURE__ */ __name((stat10, path134, type = "") => new fetch_blob_default([new BlobDataItem({
26307
+ fromBlob = /* @__PURE__ */ __name((stat11, path134, type = "") => new fetch_blob_default([new BlobDataItem({
26308
26308
  path: path134,
26309
- size: stat10.size,
26310
- lastModified: stat10.mtimeMs,
26309
+ size: stat11.size,
26310
+ lastModified: stat11.mtimeMs,
26311
26311
  start: 0
26312
26312
  })], { type }), "fromBlob");
26313
- fromFile = /* @__PURE__ */ __name((stat10, path134, type = "") => new file_default([new BlobDataItem({
26313
+ fromFile = /* @__PURE__ */ __name((stat11, path134, type = "") => new file_default([new BlobDataItem({
26314
26314
  path: path134,
26315
- size: stat10.size,
26316
- lastModified: stat10.mtimeMs,
26315
+ size: stat11.size,
26316
+ lastModified: stat11.mtimeMs,
26317
26317
  start: 0
26318
- })], basename(path134), { type, lastModified: stat10.mtimeMs }), "fromFile");
26318
+ })], basename(path134), { type, lastModified: stat11.mtimeMs }), "fromFile");
26319
26319
  BlobDataItem = class _BlobDataItem {
26320
26320
  static {
26321
26321
  __name(this, "BlobDataItem");
@@ -123779,18 +123779,18 @@ var require_async = __commonJS({
123779
123779
  ];
123780
123780
  }, "defaultPaths");
123781
123781
  var defaultIsFile = /* @__PURE__ */ __name(function isFile3(file, cb) {
123782
- fs122.stat(file, function(err, stat10) {
123782
+ fs122.stat(file, function(err, stat11) {
123783
123783
  if (!err) {
123784
- return cb(null, stat10.isFile() || stat10.isFIFO());
123784
+ return cb(null, stat11.isFile() || stat11.isFIFO());
123785
123785
  }
123786
123786
  if (err.code === "ENOENT" || err.code === "ENOTDIR") return cb(null, false);
123787
123787
  return cb(err);
123788
123788
  });
123789
123789
  }, "isFile");
123790
123790
  var defaultIsDir = /* @__PURE__ */ __name(function isDirectory(dir, cb) {
123791
- fs122.stat(dir, function(err, stat10) {
123791
+ fs122.stat(dir, function(err, stat11) {
123792
123792
  if (!err) {
123793
- return cb(null, stat10.isDirectory());
123793
+ return cb(null, stat11.isDirectory());
123794
123794
  }
123795
123795
  if (err.code === "ENOENT" || err.code === "ENOTDIR") return cb(null, false);
123796
123796
  return cb(err);
@@ -124286,21 +124286,21 @@ var require_sync = __commonJS({
124286
124286
  }, "defaultPaths");
124287
124287
  var defaultIsFile = /* @__PURE__ */ __name(function isFile3(file) {
124288
124288
  try {
124289
- var stat10 = fs122.statSync(file, { throwIfNoEntry: false });
124289
+ var stat11 = fs122.statSync(file, { throwIfNoEntry: false });
124290
124290
  } catch (e4) {
124291
124291
  if (e4 && (e4.code === "ENOENT" || e4.code === "ENOTDIR")) return false;
124292
124292
  throw e4;
124293
124293
  }
124294
- return !!stat10 && (stat10.isFile() || stat10.isFIFO());
124294
+ return !!stat11 && (stat11.isFile() || stat11.isFIFO());
124295
124295
  }, "isFile");
124296
124296
  var defaultIsDir = /* @__PURE__ */ __name(function isDirectory(dir) {
124297
124297
  try {
124298
- var stat10 = fs122.statSync(dir, { throwIfNoEntry: false });
124298
+ var stat11 = fs122.statSync(dir, { throwIfNoEntry: false });
124299
124299
  } catch (e4) {
124300
124300
  if (e4 && (e4.code === "ENOENT" || e4.code === "ENOTDIR")) return false;
124301
124301
  throw e4;
124302
124302
  }
124303
- return !!stat10 && stat10.isDirectory();
124303
+ return !!stat11 && stat11.isDirectory();
124304
124304
  }, "isDirectory");
124305
124305
  var defaultRealpathSync = /* @__PURE__ */ __name(function realpathSync8(x3) {
124306
124306
  try {
@@ -124726,14 +124726,14 @@ var require_require_in_the_middle = __commonJS({
124726
124726
  moduleName2 = parsedPath.name;
124727
124727
  basedir = parsedPath.dir;
124728
124728
  } else {
124729
- const stat10 = moduleDetailsFromPath(filename);
124730
- if (stat10 === void 0) {
124729
+ const stat11 = moduleDetailsFromPath(filename);
124730
+ if (stat11 === void 0) {
124731
124731
  debug3("could not parse filename: %s", filename);
124732
124732
  return exports3;
124733
124733
  }
124734
- moduleName2 = stat10.name;
124735
- basedir = stat10.basedir;
124736
- const fullModuleName = resolveModuleName(stat10);
124734
+ moduleName2 = stat11.name;
124735
+ basedir = stat11.basedir;
124736
+ const fullModuleName = resolveModuleName(stat11);
124737
124737
  debug3("resolved filename to module: %s (id: %s, resolved: %s, basedir: %s)", moduleName2, id, fullModuleName, basedir);
124738
124738
  let matchFound = false;
124739
124739
  if (hasWhitelist) {
@@ -124797,9 +124797,9 @@ var require_require_in_the_middle = __commonJS({
124797
124797
  }
124798
124798
  }
124799
124799
  };
124800
- function resolveModuleName(stat10) {
124801
- const normalizedPath = path134.sep !== "/" ? stat10.path.split(path134.sep).join("/") : stat10.path;
124802
- return path134.posix.join(stat10.name, normalizedPath).replace(normalize11, "");
124800
+ function resolveModuleName(stat11) {
124801
+ const normalizedPath = path134.sep !== "/" ? stat11.path.split(path134.sep).join("/") : stat11.path;
124802
+ return path134.posix.join(stat11.name, normalizedPath).replace(normalize11, "");
124803
124803
  }
124804
124804
  __name(resolveModuleName, "resolveModuleName");
124805
124805
  }
@@ -133331,6 +133331,8 @@ var init_tokenLimits = __esm({
133331
133331
  // some Sonnet 3.7/Opus variants advertise 1M beta in docs
133332
133332
  [/^claude-sonnet-4.*$/, LIMITS["1m"]],
133333
133333
  [/^claude-opus-4.*$/, LIMITS["1m"]],
133334
+ // Claude Opus 4, 4.1, 4.5 all have 200K context (using 1M as upper bound)
133335
+ [/^claude-haiku-4.*$/, LIMITS["200k"]],
133334
133336
  // -------------------
133335
133337
  // Alibaba / Qwen
133336
133338
  // -------------------
@@ -146025,6 +146027,827 @@ var init_geminiContentGenerator = __esm({
146025
146027
  }
146026
146028
  });
146027
146029
 
146030
+ // packages/core/src/core/vertexAnthropicContentGenerator.ts
146031
+ var vertexAnthropicContentGenerator_exports = {};
146032
+ __export(vertexAnthropicContentGenerator_exports, {
146033
+ VertexAnthropicContentGenerator: () => VertexAnthropicContentGenerator
146034
+ });
146035
+ var DefaultTelemetryService2, VertexAnthropicContentGenerator;
146036
+ var init_vertexAnthropicContentGenerator = __esm({
146037
+ "packages/core/src/core/vertexAnthropicContentGenerator.ts"() {
146038
+ "use strict";
146039
+ init_esbuild_shims();
146040
+ init_node();
146041
+ init_errorHandler();
146042
+ init_loggers();
146043
+ init_types();
146044
+ init_openaiLogger();
146045
+ DefaultTelemetryService2 = class {
146046
+ constructor(config2, enableLogging = false, loggingDir) {
146047
+ this.config = config2;
146048
+ this.enableLogging = enableLogging;
146049
+ this.logger = new OpenAILogger(loggingDir);
146050
+ }
146051
+ static {
146052
+ __name(this, "DefaultTelemetryService");
146053
+ }
146054
+ logger;
146055
+ async logSuccess(context2, response, request4, rawResponse) {
146056
+ const responseEvent = new ApiResponseEvent(
146057
+ response.responseId || "unknown",
146058
+ context2.model,
146059
+ context2.duration,
146060
+ context2.userPromptId,
146061
+ context2.authType,
146062
+ response.usageMetadata
146063
+ );
146064
+ logApiResponse(this.config, responseEvent);
146065
+ if (this.enableLogging && request4 && rawResponse) {
146066
+ await this.logger.logInteraction(request4, rawResponse);
146067
+ }
146068
+ }
146069
+ async logError(context2, error2, request4) {
146070
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
146071
+ const apiError = error2;
146072
+ const errorEvent = new ApiErrorEvent(
146073
+ apiError?.requestID || "unknown",
146074
+ context2.model,
146075
+ errorMessage,
146076
+ context2.duration,
146077
+ context2.userPromptId,
146078
+ context2.authType,
146079
+ apiError?.type,
146080
+ apiError?.code
146081
+ );
146082
+ logApiError(this.config, errorEvent);
146083
+ if (this.enableLogging && request4) {
146084
+ await this.logger.logInteraction(request4, void 0, error2);
146085
+ }
146086
+ }
146087
+ async logStreamingSuccess(context2, responses, request4, _chunks, combinedResponse) {
146088
+ const finalUsageMetadata = responses.slice().reverse().find((r5) => r5.usageMetadata)?.usageMetadata;
146089
+ const lastResponse = responses[responses.length - 1];
146090
+ const responseEvent = new ApiResponseEvent(
146091
+ lastResponse?.responseId || "unknown",
146092
+ context2.model,
146093
+ context2.duration,
146094
+ context2.userPromptId,
146095
+ context2.authType,
146096
+ finalUsageMetadata
146097
+ );
146098
+ logApiResponse(this.config, responseEvent);
146099
+ if (this.enableLogging && request4 && combinedResponse) {
146100
+ await this.logger.logInteraction(request4, combinedResponse);
146101
+ }
146102
+ }
146103
+ };
146104
+ VertexAnthropicContentGenerator = class {
146105
+ static {
146106
+ __name(this, "VertexAnthropicContentGenerator");
146107
+ }
146108
+ baseUrl;
146109
+ apiKey;
146110
+ samplingParams;
146111
+ reasoning;
146112
+ cliConfig;
146113
+ telemetryService;
146114
+ errorHandler;
146115
+ constructor(config2, cliConfig) {
146116
+ this.baseUrl = config2.baseUrl || "";
146117
+ this.apiKey = config2.apiKey || "";
146118
+ this.samplingParams = config2.samplingParams;
146119
+ this.reasoning = config2.reasoning;
146120
+ this.cliConfig = cliConfig;
146121
+ if (!this.apiKey) {
146122
+ throw new Error("API key is required for Vertex Anthropic");
146123
+ }
146124
+ if (!this.baseUrl) {
146125
+ throw new Error("Base URL is required for Vertex Anthropic");
146126
+ }
146127
+ if (cliConfig) {
146128
+ this.telemetryService = new DefaultTelemetryService2(
146129
+ cliConfig,
146130
+ config2.enableOpenAILogging,
146131
+ config2.openAILoggingDir
146132
+ );
146133
+ } else {
146134
+ this.telemetryService = {
146135
+ logSuccess: /* @__PURE__ */ __name(async () => {
146136
+ }, "logSuccess"),
146137
+ logError: /* @__PURE__ */ __name(async () => {
146138
+ }, "logError"),
146139
+ logStreamingSuccess: /* @__PURE__ */ __name(async () => {
146140
+ }, "logStreamingSuccess")
146141
+ };
146142
+ }
146143
+ this.errorHandler = new EnhancedErrorHandler(
146144
+ (error2, _request) => this.shouldSuppressErrorLogging(error2, _request)
146145
+ );
146146
+ }
146147
+ shouldSuppressErrorLogging(_error, _request) {
146148
+ return false;
146149
+ }
146150
+ getRequestUrl(action) {
146151
+ return `${this.baseUrl}:${action}`;
146152
+ }
146153
+ async fetchApi(url2, body, signal) {
146154
+ const headers = {
146155
+ "Content-Type": "application/json",
146156
+ "api-key": this.apiKey
146157
+ };
146158
+ if (this.cliConfig?.getDebugMode()) {
146159
+ console.debug(
146160
+ `[VertexAnthropicContentGenerator] Request URL: ${url2}`
146161
+ );
146162
+ console.debug(
146163
+ `[VertexAnthropicContentGenerator] Request body:`,
146164
+ JSON.stringify(body, null, 2)
146165
+ );
146166
+ }
146167
+ const response = await fetch(url2, {
146168
+ method: "POST",
146169
+ headers,
146170
+ body: JSON.stringify(body),
146171
+ signal
146172
+ });
146173
+ if (!response.ok) {
146174
+ const errorText = await response.text();
146175
+ if (this.cliConfig?.getDebugMode()) {
146176
+ console.error(
146177
+ `[VertexAnthropicContentGenerator] API Error (${response.status}):`,
146178
+ errorText
146179
+ );
146180
+ }
146181
+ throw new Error(
146182
+ `Vertex Anthropic API request failed: ${response.status} ${response.statusText} - ${errorText}`
146183
+ );
146184
+ }
146185
+ return response;
146186
+ }
146187
+ async convertGeminiRequestToVertexAnthropic(request4) {
146188
+ const messages = [];
146189
+ let systemInstruction;
146190
+ if (request4.config?.systemInstruction) {
146191
+ if (typeof request4.config.systemInstruction === "string") {
146192
+ systemInstruction = request4.config.systemInstruction;
146193
+ } else if ("parts" in request4.config.systemInstruction && Array.isArray(request4.config.systemInstruction.parts)) {
146194
+ systemInstruction = request4.config.systemInstruction.parts.filter((p2) => typeof p2 === "object" && "text" in p2).map((p2) => p2.text).join("\n");
146195
+ }
146196
+ }
146197
+ const contents = Array.isArray(request4.contents) ? request4.contents : [request4.contents];
146198
+ for (const content of contents) {
146199
+ if (typeof content === "string") {
146200
+ messages.push({ role: "user", content });
146201
+ } else if ("role" in content && "parts" in content && content.parts) {
146202
+ const role = content.role === "model" ? "assistant" : "user";
146203
+ const contentBlocks = this.convertPartsToAnthropicBlocks(content.parts);
146204
+ if (contentBlocks.length > 0) {
146205
+ if (contentBlocks.length === 1 && contentBlocks[0].type === "text") {
146206
+ messages.push({ role, content: contentBlocks[0].text });
146207
+ } else {
146208
+ messages.push({ role, content: contentBlocks });
146209
+ }
146210
+ }
146211
+ }
146212
+ }
146213
+ const temperature = this.samplingParams?.temperature ?? 1;
146214
+ const thinking = this.buildThinkingConfig(request4);
146215
+ const defaultMaxTokens = thinking ? thinking.budget_tokens + 16e3 : 1e4;
146216
+ const maxTokens = this.samplingParams?.max_tokens ?? defaultMaxTokens;
146217
+ const vertexRequest = {
146218
+ anthropic_version: "vertex-2023-10-16",
146219
+ messages,
146220
+ max_tokens: maxTokens,
146221
+ temperature
146222
+ };
146223
+ if (systemInstruction) {
146224
+ vertexRequest.system = systemInstruction;
146225
+ }
146226
+ if (this.samplingParams?.top_p !== void 0) {
146227
+ vertexRequest.top_p = this.samplingParams.top_p;
146228
+ }
146229
+ if (this.samplingParams?.top_k !== void 0) {
146230
+ vertexRequest.top_k = this.samplingParams.top_k;
146231
+ }
146232
+ if (thinking) {
146233
+ vertexRequest.thinking = thinking;
146234
+ }
146235
+ if (request4.config?.tools && request4.config.tools.length > 0) {
146236
+ const tools = await this.convertGeminiToolsToAnthropic(
146237
+ request4.config.tools
146238
+ );
146239
+ if (tools.length > 0) {
146240
+ vertexRequest.tools = tools;
146241
+ }
146242
+ }
146243
+ return vertexRequest;
146244
+ }
146245
+ buildThinkingConfig(request4) {
146246
+ if (request4.config?.thinkingConfig?.includeThoughts === false) {
146247
+ return void 0;
146248
+ }
146249
+ const reasoning = this.reasoning;
146250
+ if (reasoning === false) {
146251
+ return void 0;
146252
+ }
146253
+ if (reasoning?.budget_tokens !== void 0) {
146254
+ return {
146255
+ type: "enabled",
146256
+ budget_tokens: reasoning.budget_tokens
146257
+ };
146258
+ }
146259
+ const effort = reasoning?.effort ?? "medium";
146260
+ const budgetTokens = effort === "low" ? 16e3 : effort === "high" ? 64e3 : 32e3;
146261
+ return {
146262
+ type: "enabled",
146263
+ budget_tokens: budgetTokens
146264
+ };
146265
+ }
146266
+ /**
146267
+ * 将 Gemini Part 数组转换为 Anthropic 内容块数组
146268
+ */
146269
+ convertPartsToAnthropicBlocks(parts) {
146270
+ const blocks = [];
146271
+ for (const part of parts) {
146272
+ const block2 = this.convertPartToAnthropicBlock(part);
146273
+ if (block2) {
146274
+ blocks.push(block2);
146275
+ }
146276
+ }
146277
+ return blocks;
146278
+ }
146279
+ /**
146280
+ * 将单个 Gemini Part 转换为 Anthropic 内容块
146281
+ */
146282
+ convertPartToAnthropicBlock(part) {
146283
+ if ("text" in part && "thought" in part && part.thought) {
146284
+ const thinkingBlock = {
146285
+ type: "thinking",
146286
+ thinking: part.text || ""
146287
+ };
146288
+ if ("thoughtSignature" in part && typeof part.thoughtSignature === "string") {
146289
+ thinkingBlock.signature = part.thoughtSignature;
146290
+ }
146291
+ return thinkingBlock;
146292
+ }
146293
+ if ("text" in part && part.text && !("thought" in part && part.thought)) {
146294
+ return { type: "text", text: part.text };
146295
+ }
146296
+ if (part.inlineData?.mimeType && part.inlineData?.data) {
146297
+ const mimeType = part.inlineData.mimeType;
146298
+ if (this.isSupportedImageMimeType(mimeType)) {
146299
+ return {
146300
+ type: "image",
146301
+ source: {
146302
+ type: "base64",
146303
+ media_type: mimeType,
146304
+ data: part.inlineData.data
146305
+ }
146306
+ };
146307
+ }
146308
+ if (mimeType === "application/pdf") {
146309
+ return {
146310
+ type: "document",
146311
+ source: {
146312
+ type: "base64",
146313
+ media_type: "application/pdf",
146314
+ data: part.inlineData.data
146315
+ }
146316
+ };
146317
+ }
146318
+ const displayName = part.inlineData.displayName ? ` (${part.inlineData.displayName})` : "";
146319
+ return {
146320
+ type: "text",
146321
+ text: `[Unsupported media type: ${mimeType}${displayName}]`
146322
+ };
146323
+ }
146324
+ if (part.fileData?.mimeType && part.fileData?.fileUri) {
146325
+ return {
146326
+ type: "text",
146327
+ text: `[External file reference: ${part.fileData.fileUri}]`
146328
+ };
146329
+ }
146330
+ if ("functionCall" in part && part.functionCall) {
146331
+ return {
146332
+ type: "tool_use",
146333
+ id: part.functionCall.id || `tool_${Date.now()}`,
146334
+ name: part.functionCall.name || "",
146335
+ input: part.functionCall.args || {}
146336
+ };
146337
+ }
146338
+ if ("functionResponse" in part && part.functionResponse) {
146339
+ const response = part.functionResponse;
146340
+ let content;
146341
+ if (response.response) {
146342
+ content = JSON.stringify(response.response);
146343
+ } else {
146344
+ content = "";
146345
+ }
146346
+ return {
146347
+ type: "tool_result",
146348
+ tool_use_id: response.id || "",
146349
+ content
146350
+ };
146351
+ }
146352
+ return null;
146353
+ }
146354
+ /**
146355
+ * 检查是否是 Anthropic 支持的图片类型
146356
+ */
146357
+ isSupportedImageMimeType(mimeType) {
146358
+ return mimeType === "image/jpeg" || mimeType === "image/png" || mimeType === "image/gif" || mimeType === "image/webp";
146359
+ }
146360
+ /**
146361
+ * 将 Gemini 工具定义转换为 Anthropic 格式
146362
+ * 参考 AnthropicContentConverter.convertGeminiToolsToAnthropic
146363
+ */
146364
+ async convertGeminiToolsToAnthropic(geminiTools) {
146365
+ const tools = [];
146366
+ if (!geminiTools) {
146367
+ return tools;
146368
+ }
146369
+ for (const tool of geminiTools) {
146370
+ let actualTool;
146371
+ const toolObj = tool;
146372
+ if ("tool" in toolObj && typeof toolObj["tool"] === "function") {
146373
+ actualTool = await toolObj["tool"]();
146374
+ } else {
146375
+ actualTool = tool;
146376
+ }
146377
+ if (!actualTool.functionDeclarations) {
146378
+ continue;
146379
+ }
146380
+ for (const func of actualTool.functionDeclarations) {
146381
+ if (!func.name) continue;
146382
+ let inputSchema;
146383
+ if (func.parametersJsonSchema) {
146384
+ inputSchema = {
146385
+ ...func.parametersJsonSchema
146386
+ };
146387
+ } else if (func.parameters) {
146388
+ inputSchema = func.parameters;
146389
+ }
146390
+ if (!inputSchema) {
146391
+ inputSchema = { type: "object", properties: {} };
146392
+ }
146393
+ if (typeof inputSchema["type"] !== "string") {
146394
+ inputSchema["type"] = "object";
146395
+ }
146396
+ tools.push({
146397
+ name: func.name,
146398
+ description: func.description,
146399
+ input_schema: inputSchema
146400
+ });
146401
+ }
146402
+ }
146403
+ return tools;
146404
+ }
146405
+ convertVertexAnthropicResponseToGemini(response) {
146406
+ const parts = [];
146407
+ for (const content of response.content) {
146408
+ if (content.type === "text" && content.text) {
146409
+ parts.push({ text: content.text });
146410
+ } else if (content.type === "thinking" && content.thinking) {
146411
+ const thinkingPart = { text: content.thinking, thought: true };
146412
+ if (content.signature) {
146413
+ thinkingPart.thoughtSignature = content.signature;
146414
+ }
146415
+ parts.push(thinkingPart);
146416
+ } else if (content.type === "tool_use" && content.name && content.id) {
146417
+ parts.push({
146418
+ functionCall: {
146419
+ name: content.name,
146420
+ args: content.input || {},
146421
+ id: content.id
146422
+ }
146423
+ });
146424
+ }
146425
+ }
146426
+ const result = {
146427
+ responseId: response.id,
146428
+ modelVersion: response.model,
146429
+ candidates: [
146430
+ {
146431
+ content: {
146432
+ parts,
146433
+ role: "model"
146434
+ },
146435
+ index: 0,
146436
+ finishReason: this.mapFinishReason(response.stop_reason),
146437
+ safetyRatings: []
146438
+ }
146439
+ ],
146440
+ promptFeedback: { safetyRatings: [] },
146441
+ usageMetadata: {
146442
+ promptTokenCount: response.usage.input_tokens,
146443
+ candidatesTokenCount: response.usage.output_tokens,
146444
+ totalTokenCount: response.usage.input_tokens + response.usage.output_tokens
146445
+ }
146446
+ };
146447
+ return result;
146448
+ }
146449
+ mapFinishReason(stopReason) {
146450
+ if (!stopReason) {
146451
+ return void 0;
146452
+ }
146453
+ switch (stopReason) {
146454
+ case "end_turn":
146455
+ return FinishReason.STOP;
146456
+ case "max_tokens":
146457
+ return FinishReason.MAX_TOKENS;
146458
+ case "stop_sequence":
146459
+ return FinishReason.STOP;
146460
+ case "tool_use":
146461
+ return FinishReason.STOP;
146462
+ default:
146463
+ return FinishReason.OTHER;
146464
+ }
146465
+ }
146466
+ /**
146467
+ * 安全解析 JSON,失败时返回默认值
146468
+ */
146469
+ safeJsonParse(jsonStr, defaultValue) {
146470
+ try {
146471
+ return JSON.parse(jsonStr);
146472
+ } catch {
146473
+ return defaultValue;
146474
+ }
146475
+ }
146476
+ async generateContent(request4, userPromptId) {
146477
+ const startTime = Date.now();
146478
+ const context2 = {
146479
+ userPromptId,
146480
+ model: request4.model,
146481
+ authType: "xhs-sso",
146482
+ startTime,
146483
+ duration: 0,
146484
+ isStreaming: false
146485
+ };
146486
+ try {
146487
+ const url2 = this.getRequestUrl("rawPredict");
146488
+ const body = await this.convertGeminiRequestToVertexAnthropic(request4);
146489
+ const response = await this.fetchApi(
146490
+ url2,
146491
+ body,
146492
+ request4.config?.abortSignal
146493
+ );
146494
+ const data = await response.json();
146495
+ context2.duration = Date.now() - startTime;
146496
+ const geminiResponse = this.convertVertexAnthropicResponseToGemini(data);
146497
+ await this.telemetryService.logSuccess(context2, geminiResponse, body, data);
146498
+ return geminiResponse;
146499
+ } catch (error2) {
146500
+ context2.duration = Date.now() - startTime;
146501
+ await this.telemetryService.logError(context2, error2, request4);
146502
+ return this.errorHandler.handle(error2, context2, request4);
146503
+ }
146504
+ }
146505
+ async generateContentStream(request4, userPromptId) {
146506
+ const startTime = Date.now();
146507
+ const context2 = {
146508
+ userPromptId,
146509
+ model: request4.model,
146510
+ authType: "xhs-sso",
146511
+ startTime,
146512
+ duration: 0,
146513
+ isStreaming: true
146514
+ };
146515
+ try {
146516
+ const url2 = this.getRequestUrl("streamRawPredict");
146517
+ const baseBody = await this.convertGeminiRequestToVertexAnthropic(request4);
146518
+ const body = {
146519
+ ...baseBody,
146520
+ stream: true
146521
+ };
146522
+ const response = await this.fetchApi(
146523
+ url2,
146524
+ body,
146525
+ request4.config?.abortSignal
146526
+ );
146527
+ if (!response.body) {
146528
+ throw new Error("Response body is null");
146529
+ }
146530
+ const stream2 = this.handleStream(response.body);
146531
+ const collectedResponses = [];
146532
+ return async function* () {
146533
+ try {
146534
+ for await (const chunk of stream2) {
146535
+ collectedResponses.push(chunk);
146536
+ yield chunk;
146537
+ }
146538
+ context2.duration = Date.now() - startTime;
146539
+ const combinedResponse = this.combineResponses(collectedResponses);
146540
+ await this.telemetryService.logStreamingSuccess(
146541
+ context2,
146542
+ collectedResponses,
146543
+ body,
146544
+ void 0,
146545
+ combinedResponse
146546
+ );
146547
+ } catch (error2) {
146548
+ context2.duration = Date.now() - startTime;
146549
+ await this.telemetryService.logError(context2, error2, body);
146550
+ throw error2;
146551
+ }
146552
+ }.call(this);
146553
+ } catch (error2) {
146554
+ context2.duration = Date.now() - startTime;
146555
+ await this.telemetryService.logError(context2, error2, request4);
146556
+ return this.errorHandler.handle(error2, context2, request4);
146557
+ }
146558
+ }
146559
+ combineResponses(responses) {
146560
+ if (responses.length === 0) {
146561
+ return {};
146562
+ }
146563
+ const lastResponse = responses[responses.length - 1];
146564
+ let combinedText = "";
146565
+ for (const response of responses) {
146566
+ if (response.candidates && response.candidates[0]?.content?.parts) {
146567
+ for (const part of response.candidates[0].content.parts) {
146568
+ if ("text" in part && part.text) {
146569
+ combinedText += part.text;
146570
+ }
146571
+ }
146572
+ }
146573
+ }
146574
+ return {
146575
+ ...lastResponse,
146576
+ candidates: lastResponse.candidates ? [
146577
+ {
146578
+ ...lastResponse.candidates[0],
146579
+ content: {
146580
+ ...lastResponse.candidates[0].content,
146581
+ parts: [{ text: combinedText }]
146582
+ }
146583
+ }
146584
+ ] : void 0
146585
+ };
146586
+ }
146587
+ async *handleStream(body) {
146588
+ const reader = body.getReader();
146589
+ const decoder = new TextDecoder();
146590
+ let buffer = "";
146591
+ let currentEvent = "";
146592
+ let messageId;
146593
+ let model = "";
146594
+ let cachedTokens = 0;
146595
+ let promptTokens = 0;
146596
+ let completionTokens = 0;
146597
+ let finishReason;
146598
+ const blocks = /* @__PURE__ */ new Map();
146599
+ try {
146600
+ while (true) {
146601
+ const { done, value } = await reader.read();
146602
+ if (done) break;
146603
+ buffer += decoder.decode(value, { stream: true });
146604
+ const lines = buffer.split("\n");
146605
+ buffer = lines.pop() || "";
146606
+ for (const line of lines) {
146607
+ const trimmedLine = line.trim();
146608
+ if (!trimmedLine) {
146609
+ currentEvent = "";
146610
+ continue;
146611
+ }
146612
+ if (trimmedLine.startsWith("event: ")) {
146613
+ currentEvent = trimmedLine.slice(7).trim();
146614
+ continue;
146615
+ }
146616
+ if (trimmedLine.startsWith("data: ")) {
146617
+ const dataStr = trimmedLine.slice(6).trim();
146618
+ if (!dataStr || dataStr === "[DONE]") continue;
146619
+ try {
146620
+ const data = JSON.parse(dataStr);
146621
+ const eventType = data.type || currentEvent;
146622
+ switch (eventType) {
146623
+ case "message_start": {
146624
+ if (data.message) {
146625
+ messageId = data.message.id ?? messageId;
146626
+ model = data.message.model ?? model;
146627
+ if (data.message.usage) {
146628
+ cachedTokens = data.message.usage.cache_read_input_tokens ?? 0;
146629
+ promptTokens = data.message.usage.input_tokens ?? 0;
146630
+ }
146631
+ }
146632
+ break;
146633
+ }
146634
+ case "content_block_start": {
146635
+ const index = data.index ?? 0;
146636
+ const type = String(data.content_block?.type || "text");
146637
+ const initialInput = type === "tool_use" && data.content_block?.input ? JSON.stringify(data.content_block.input) : "";
146638
+ const initialSignature = type === "thinking" && data.content_block?.signature ? String(data.content_block.signature) : "";
146639
+ if (this.cliConfig?.getDebugMode() && type === "tool_use") {
146640
+ console.debug(
146641
+ `[VertexAnthropicContentGenerator] Tool use block start:`,
146642
+ JSON.stringify({
146643
+ index,
146644
+ id: data.content_block?.id,
146645
+ name: data.content_block?.name,
146646
+ initialInput
146647
+ })
146648
+ );
146649
+ }
146650
+ blocks.set(index, {
146651
+ type,
146652
+ id: type === "tool_use" ? String(data.content_block?.id || "") : void 0,
146653
+ name: type === "tool_use" ? String(data.content_block?.name || "") : void 0,
146654
+ // SDK 兼容:如果初始 input 是空对象 {},则设为空字符串
146655
+ // 实际参数通过后续的 input_json_delta 事件发送
146656
+ inputJson: initialInput !== "{}" ? initialInput : "",
146657
+ signature: initialSignature
146658
+ });
146659
+ break;
146660
+ }
146661
+ case "content_block_delta": {
146662
+ const deltaType = data.delta?.type;
146663
+ const index = data.index ?? 0;
146664
+ if (deltaType === "text_delta" && data.delta?.text) {
146665
+ const chunk = this.buildGeminiChunk(
146666
+ { text: data.delta.text },
146667
+ messageId,
146668
+ model
146669
+ );
146670
+ yield chunk;
146671
+ } else if (deltaType === "thinking_delta" && data.delta?.thinking) {
146672
+ const chunk = this.buildGeminiChunk(
146673
+ { text: data.delta.thinking, thought: true },
146674
+ messageId,
146675
+ model
146676
+ );
146677
+ yield chunk;
146678
+ } else if (deltaType === "input_json_delta" && data.delta?.partial_json) {
146679
+ const blockState = blocks.get(index);
146680
+ if (blockState) {
146681
+ blockState.inputJson += data.delta.partial_json;
146682
+ if (this.cliConfig?.getDebugMode()) {
146683
+ console.debug(
146684
+ `[VertexAnthropicContentGenerator] input_json_delta:`,
146685
+ data.delta.partial_json
146686
+ );
146687
+ }
146688
+ }
146689
+ } else if (deltaType === "signature_delta" && data.delta?.signature) {
146690
+ const blockState = blocks.get(index);
146691
+ if (blockState) {
146692
+ blockState.signature += data.delta.signature;
146693
+ const chunk = this.buildGeminiChunk(
146694
+ { thought: true, thoughtSignature: data.delta.signature },
146695
+ messageId,
146696
+ model
146697
+ );
146698
+ yield chunk;
146699
+ }
146700
+ }
146701
+ break;
146702
+ }
146703
+ case "content_block_stop": {
146704
+ const index = data.index ?? 0;
146705
+ const blockState = blocks.get(index);
146706
+ if (blockState?.type === "tool_use") {
146707
+ const args = this.safeJsonParse(blockState.inputJson || "{}", {});
146708
+ if (this.cliConfig?.getDebugMode()) {
146709
+ console.debug(
146710
+ `[VertexAnthropicContentGenerator] Tool use block stop:`,
146711
+ JSON.stringify({
146712
+ index,
146713
+ id: blockState.id,
146714
+ name: blockState.name,
146715
+ inputJson: blockState.inputJson,
146716
+ parsedArgs: args
146717
+ })
146718
+ );
146719
+ }
146720
+ const chunk = this.buildGeminiChunk(
146721
+ {
146722
+ functionCall: {
146723
+ id: blockState.id,
146724
+ name: blockState.name,
146725
+ args
146726
+ }
146727
+ },
146728
+ messageId,
146729
+ model
146730
+ );
146731
+ yield chunk;
146732
+ }
146733
+ blocks.delete(index);
146734
+ break;
146735
+ }
146736
+ case "message_delta": {
146737
+ if (data.delta?.stop_reason) {
146738
+ finishReason = data.delta.stop_reason;
146739
+ }
146740
+ if (data.usage?.output_tokens !== void 0) {
146741
+ completionTokens = data.usage.output_tokens;
146742
+ }
146743
+ if (finishReason || data.usage) {
146744
+ const chunk = this.buildGeminiChunk(
146745
+ void 0,
146746
+ messageId,
146747
+ model,
146748
+ finishReason,
146749
+ {
146750
+ cachedContentTokenCount: cachedTokens,
146751
+ promptTokenCount: cachedTokens + promptTokens,
146752
+ candidatesTokenCount: completionTokens,
146753
+ totalTokenCount: cachedTokens + promptTokens + completionTokens
146754
+ }
146755
+ );
146756
+ yield chunk;
146757
+ }
146758
+ break;
146759
+ }
146760
+ case "message_stop": {
146761
+ if (promptTokens || completionTokens) {
146762
+ const chunk = this.buildGeminiChunk(
146763
+ void 0,
146764
+ messageId,
146765
+ model,
146766
+ finishReason,
146767
+ {
146768
+ cachedContentTokenCount: cachedTokens,
146769
+ promptTokenCount: cachedTokens + promptTokens,
146770
+ candidatesTokenCount: completionTokens,
146771
+ totalTokenCount: cachedTokens + promptTokens + completionTokens
146772
+ }
146773
+ );
146774
+ yield chunk;
146775
+ }
146776
+ break;
146777
+ }
146778
+ default:
146779
+ break;
146780
+ }
146781
+ } catch (error2) {
146782
+ if (this.cliConfig?.getDebugMode()) {
146783
+ console.error(
146784
+ `[VertexAnthropicContentGenerator] Failed to parse SSE data:`,
146785
+ dataStr,
146786
+ error2
146787
+ );
146788
+ }
146789
+ }
146790
+ }
146791
+ }
146792
+ }
146793
+ } finally {
146794
+ reader.releaseLock();
146795
+ }
146796
+ }
146797
+ buildGeminiChunk(part, responseId, model, finishReason, usageMetadata) {
146798
+ const response = new GenerateContentResponse();
146799
+ response.responseId = responseId;
146800
+ response.createTime = Date.now().toString();
146801
+ response.modelVersion = model || "";
146802
+ response.promptFeedback = { safetyRatings: [] };
146803
+ let candidateParts = [];
146804
+ if (part) {
146805
+ if (part.functionCall) {
146806
+ candidateParts = [
146807
+ {
146808
+ functionCall: {
146809
+ name: part.functionCall.name || "",
146810
+ args: part.functionCall.args || {},
146811
+ id: part.functionCall.id
146812
+ }
146813
+ }
146814
+ ];
146815
+ } else {
146816
+ candidateParts = [part];
146817
+ }
146818
+ }
146819
+ const mappedFinishReason = finishReason ? this.mapFinishReason(finishReason) : void 0;
146820
+ response.candidates = [
146821
+ {
146822
+ content: {
146823
+ parts: candidateParts,
146824
+ role: "model"
146825
+ },
146826
+ index: 0,
146827
+ safetyRatings: [],
146828
+ ...mappedFinishReason ? { finishReason: mappedFinishReason } : {}
146829
+ }
146830
+ ];
146831
+ if (usageMetadata) {
146832
+ response.usageMetadata = usageMetadata;
146833
+ }
146834
+ return response;
146835
+ }
146836
+ async countTokens(request4) {
146837
+ const content = JSON.stringify(request4.contents);
146838
+ const totalTokens = Math.ceil(content.length / 4);
146839
+ return { totalTokens };
146840
+ }
146841
+ async embedContent(_request) {
146842
+ throw new Error("Vertex Anthropic does not support embeddings.");
146843
+ }
146844
+ useSummarizedThinking() {
146845
+ return false;
146846
+ }
146847
+ };
146848
+ }
146849
+ });
146850
+
146028
146851
  // node_modules/@anthropic-ai/sdk/version.mjs
146029
146852
  var VERSION3;
146030
146853
  var init_version3 = __esm({
@@ -157557,7 +158380,7 @@ __export(geminiContentGenerator_exports2, {
157557
158380
  createGeminiContentGenerator: () => createGeminiContentGenerator
157558
158381
  });
157559
158382
  function createGeminiContentGenerator(config2, gcConfig) {
157560
- const version2 = "0.2.3-alpha.2";
158383
+ const version2 = "0.2.3-alpha.4";
157561
158384
  const userAgent2 = config2.userAgent || `QwenCode/${version2} (${process.platform}; ${process.arch})`;
157562
158385
  const baseHeaders = {
157563
158386
  "User-Agent": userAgent2
@@ -157732,6 +158555,12 @@ async function createContentGenerator(generatorConfig, config2, isInitialAuth) {
157732
158555
  if (model.startsWith("gemini")) {
157733
158556
  const { GeminiContentGenerator: GeminiContentGenerator3 } = await Promise.resolve().then(() => (init_geminiContentGenerator(), geminiContentGenerator_exports));
157734
158557
  baseGenerator = new GeminiContentGenerator3(generatorConfig, config2);
158558
+ } else if (model.startsWith("claude")) {
158559
+ const { VertexAnthropicContentGenerator: VertexAnthropicContentGenerator2 } = await Promise.resolve().then(() => (init_vertexAnthropicContentGenerator(), vertexAnthropicContentGenerator_exports));
158560
+ baseGenerator = new VertexAnthropicContentGenerator2(
158561
+ generatorConfig,
158562
+ config2
158563
+ );
157735
158564
  } else {
157736
158565
  const { createOpenAIContentGenerator: createOpenAIContentGenerator2 } = await Promise.resolve().then(() => (init_openaiContentGenerator2(), openaiContentGenerator_exports));
157737
158566
  baseGenerator = createOpenAIContentGenerator2(generatorConfig, config2);
@@ -190463,12 +191292,12 @@ var require_src36 = __commonJS({
190463
191292
  function check2(path134, isFile3, isDirectory) {
190464
191293
  log(`checking %s`, path134);
190465
191294
  try {
190466
- const stat10 = fs_1.statSync(path134);
190467
- if (stat10.isFile() && isFile3) {
191295
+ const stat11 = fs_1.statSync(path134);
191296
+ if (stat11.isFile() && isFile3) {
190468
191297
  log(`[OK] path represents a file`);
190469
191298
  return true;
190470
191299
  }
190471
- if (stat10.isDirectory() && isDirectory) {
191300
+ if (stat11.isDirectory() && isDirectory) {
190472
191301
  log(`[OK] path represents a directory`);
190473
191302
  return true;
190474
191303
  }
@@ -206564,16 +207393,16 @@ var require_windows = __commonJS({
206564
207393
  return false;
206565
207394
  }
206566
207395
  __name(checkPathExt, "checkPathExt");
206567
- function checkStat(stat10, path134, options2) {
206568
- if (!stat10.isSymbolicLink() && !stat10.isFile()) {
207396
+ function checkStat(stat11, path134, options2) {
207397
+ if (!stat11.isSymbolicLink() && !stat11.isFile()) {
206569
207398
  return false;
206570
207399
  }
206571
207400
  return checkPathExt(path134, options2);
206572
207401
  }
206573
207402
  __name(checkStat, "checkStat");
206574
207403
  function isexe(path134, options2, cb) {
206575
- fs122.stat(path134, function(er2, stat10) {
206576
- cb(er2, er2 ? false : checkStat(stat10, path134, options2));
207404
+ fs122.stat(path134, function(er2, stat11) {
207405
+ cb(er2, er2 ? false : checkStat(stat11, path134, options2));
206577
207406
  });
206578
207407
  }
206579
207408
  __name(isexe, "isexe");
@@ -206592,8 +207421,8 @@ var require_mode = __commonJS({
206592
207421
  isexe.sync = sync2;
206593
207422
  var fs122 = __require("fs");
206594
207423
  function isexe(path134, options2, cb) {
206595
- fs122.stat(path134, function(er2, stat10) {
206596
- cb(er2, er2 ? false : checkStat(stat10, options2));
207424
+ fs122.stat(path134, function(er2, stat11) {
207425
+ cb(er2, er2 ? false : checkStat(stat11, options2));
206597
207426
  });
206598
207427
  }
206599
207428
  __name(isexe, "isexe");
@@ -206601,14 +207430,14 @@ var require_mode = __commonJS({
206601
207430
  return checkStat(fs122.statSync(path134), options2);
206602
207431
  }
206603
207432
  __name(sync2, "sync");
206604
- function checkStat(stat10, options2) {
206605
- return stat10.isFile() && checkMode(stat10, options2);
207433
+ function checkStat(stat11, options2) {
207434
+ return stat11.isFile() && checkMode(stat11, options2);
206606
207435
  }
206607
207436
  __name(checkStat, "checkStat");
206608
- function checkMode(stat10, options2) {
206609
- var mod2 = stat10.mode;
206610
- var uid = stat10.uid;
206611
- var gid = stat10.gid;
207437
+ function checkMode(stat11, options2) {
207438
+ var mod2 = stat11.mode;
207439
+ var uid = stat11.uid;
207440
+ var gid = stat11.gid;
206612
207441
  var myUid = options2.uid !== void 0 ? options2.uid : process.getuid && process.getuid();
206613
207442
  var myGid = options2.gid !== void 0 ? options2.gid : process.getgid && process.getgid();
206614
207443
  var u2 = parseInt("100", 8);
@@ -207802,14 +208631,14 @@ var init_ide_client = __esm({
207802
208631
  lockFiles.map(async (file) => {
207803
208632
  const fullPath = path34.join(ideDir, file);
207804
208633
  try {
207805
- const stat10 = await fs34.promises.stat(fullPath);
208634
+ const stat11 = await fs34.promises.stat(fullPath);
207806
208635
  const content = await fs34.promises.readFile(fullPath, "utf8");
207807
208636
  try {
207808
208637
  const parsed = JSON.parse(content);
207809
- return { file, mtimeMs: stat10.mtimeMs, parsed };
208638
+ return { file, mtimeMs: stat11.mtimeMs, parsed };
207810
208639
  } catch (e4) {
207811
208640
  logger.debug("Failed to parse JSON from lock file: ", e4);
207812
- return { file, mtimeMs: stat10.mtimeMs, parsed: void 0 };
208641
+ return { file, mtimeMs: stat11.mtimeMs, parsed: void 0 };
207813
208642
  }
207814
208643
  } catch (e4) {
207815
208644
  logger.debug("Failed to read/stat IDE lock file:", e4);
@@ -215943,6 +216772,19 @@ var init_mcp_client = __esm({
215943
216772
  getStatus() {
215944
216773
  return this.status;
215945
216774
  }
216775
+ async readResource(uri, options2) {
216776
+ if (this.status !== "connected" /* CONNECTED */) {
216777
+ throw new Error("Client is not connected.");
216778
+ }
216779
+ if (this.client.getServerCapabilities()?.resources == null) {
216780
+ throw new Error("MCP server does not support resources.");
216781
+ }
216782
+ return this.client.request(
216783
+ { method: "resources/read", params: { uri } },
216784
+ ReadResourceResultSchema,
216785
+ options2
216786
+ );
216787
+ }
215946
216788
  updateStatus(status) {
215947
216789
  this.status = status;
215948
216790
  updateMCPServerStatus(this.serverName, status);
@@ -216065,6 +216907,59 @@ var init_mcp_client_manager = __esm({
216065
216907
  await Promise.all(discoveryPromises);
216066
216908
  this.discoveryState = "completed" /* COMPLETED */;
216067
216909
  }
216910
+ /**
216911
+ * Connects to a single MCP server and discovers its tools/prompts.
216912
+ * The connected client is tracked so it can be closed by {@link stop}.
216913
+ *
216914
+ * This is primarily used for on-demand re-discovery flows (e.g. after OAuth).
216915
+ */
216916
+ async discoverMcpToolsForServer(serverName, cliConfig) {
216917
+ const servers = populateMcpServerCommand(
216918
+ this.cliConfig.getMcpServers() || {},
216919
+ this.cliConfig.getMcpServerCommand()
216920
+ );
216921
+ const serverConfig = servers[serverName];
216922
+ if (!serverConfig) {
216923
+ return;
216924
+ }
216925
+ const existingClient = this.clients.get(serverName);
216926
+ if (existingClient) {
216927
+ try {
216928
+ await existingClient.disconnect();
216929
+ } catch (error2) {
216930
+ console.error(
216931
+ `Error stopping client '${serverName}': ${getErrorMessage(error2)}`
216932
+ );
216933
+ } finally {
216934
+ this.clients.delete(serverName);
216935
+ this.eventEmitter?.emit("mcp-client-update", this.clients);
216936
+ }
216937
+ }
216938
+ const sdkCallback = isSdkMcpServerConfig(serverConfig) ? this.sendSdkMcpMessage : void 0;
216939
+ const client = new McpClient(
216940
+ serverName,
216941
+ serverConfig,
216942
+ this.toolRegistry,
216943
+ this.cliConfig.getPromptRegistry(),
216944
+ this.cliConfig.getWorkspaceContext(),
216945
+ this.cliConfig.getDebugMode(),
216946
+ sdkCallback
216947
+ );
216948
+ this.clients.set(serverName, client);
216949
+ this.eventEmitter?.emit("mcp-client-update", this.clients);
216950
+ try {
216951
+ await client.connect();
216952
+ await client.discover(cliConfig);
216953
+ } catch (error2) {
216954
+ console.error(
216955
+ `Error during discovery for server '${serverName}': ${getErrorMessage(
216956
+ error2
216957
+ )}`
216958
+ );
216959
+ } finally {
216960
+ this.eventEmitter?.emit("mcp-client-update", this.clients);
216961
+ }
216962
+ }
216068
216963
  /**
216069
216964
  * Stops all running local MCP servers and closes all client connections.
216070
216965
  * This is the cleanup method to be called on application exit.
@@ -216087,6 +216982,35 @@ var init_mcp_client_manager = __esm({
216087
216982
  getDiscoveryState() {
216088
216983
  return this.discoveryState;
216089
216984
  }
216985
+ async readResource(serverName, uri, options2) {
216986
+ let client = this.clients.get(serverName);
216987
+ if (!client) {
216988
+ const servers = populateMcpServerCommand(
216989
+ this.cliConfig.getMcpServers() || {},
216990
+ this.cliConfig.getMcpServerCommand()
216991
+ );
216992
+ const serverConfig = servers[serverName];
216993
+ if (!serverConfig) {
216994
+ throw new Error(`MCP server '${serverName}' is not configured.`);
216995
+ }
216996
+ const sdkCallback = isSdkMcpServerConfig(serverConfig) ? this.sendSdkMcpMessage : void 0;
216997
+ client = new McpClient(
216998
+ serverName,
216999
+ serverConfig,
217000
+ this.toolRegistry,
217001
+ this.cliConfig.getPromptRegistry(),
217002
+ this.cliConfig.getWorkspaceContext(),
217003
+ this.cliConfig.getDebugMode(),
217004
+ sdkCallback
217005
+ );
217006
+ this.clients.set(serverName, client);
217007
+ this.eventEmitter?.emit("mcp-client-update", this.clients);
217008
+ }
217009
+ if (client.getStatus() !== "connected" /* CONNECTED */) {
217010
+ await client.connect();
217011
+ }
217012
+ return client.readResource(uri, options2);
217013
+ }
216090
217014
  };
216091
217015
  }
216092
217016
  });
@@ -216100,7 +217024,6 @@ var init_tool_registry = __esm({
216100
217024
  "use strict";
216101
217025
  init_esbuild_shims();
216102
217026
  init_tools();
216103
- init_mcp_client();
216104
217027
  init_mcp_client_manager();
216105
217028
  init_mcp_tool();
216106
217029
  import_shell_quote4 = __toESM(require_shell_quote(), 1);
@@ -216312,19 +217235,10 @@ Signal: Signal number or \`(none)\` if no signal was received.
216312
217235
  }
216313
217236
  }
216314
217237
  this.config.getPromptRegistry().removePromptsByServer(serverName);
216315
- const mcpServers = this.config.getMcpServers() ?? {};
216316
- const serverConfig = mcpServers[serverName];
216317
- if (serverConfig) {
216318
- await connectAndDiscover(
216319
- serverName,
216320
- serverConfig,
216321
- this,
216322
- this.config.getPromptRegistry(),
216323
- this.config.getDebugMode(),
216324
- this.config.getWorkspaceContext(),
216325
- this.config
216326
- );
216327
- }
217238
+ await this.mcpClientManager.discoverMcpToolsForServer(
217239
+ serverName,
217240
+ this.config
217241
+ );
216328
217242
  }
216329
217243
  async discoverAndRegisterToolsFromCommand() {
216330
217244
  const discoveryCmd = this.config.getToolDiscoveryCommand();
@@ -216488,6 +217402,23 @@ Signal: Signal number or \`(none)\` if no signal was received.
216488
217402
  getTool(name3) {
216489
217403
  return this.tools.get(name3);
216490
217404
  }
217405
+ async readMcpResource(serverName, uri, options2) {
217406
+ if (!this.config.isTrustedFolder()) {
217407
+ throw new Error("MCP resources are unavailable in untrusted folders.");
217408
+ }
217409
+ return this.mcpClientManager.readResource(serverName, uri, options2);
217410
+ }
217411
+ /**
217412
+ * Stops all MCP clients and cleans up resources.
217413
+ * This method is idempotent and safe to call multiple times.
217414
+ */
217415
+ async stop() {
217416
+ try {
217417
+ await this.mcpClientManager.stop();
217418
+ } catch (error2) {
217419
+ console.error("Error stopping MCP clients:", error2);
217420
+ }
217421
+ }
216491
217422
  };
216492
217423
  }
216493
217424
  });
@@ -222124,7 +223055,7 @@ ${textContent2}
222124
223055
  return `Fetching content from ${this.params.url} and processing with prompt: "${displayPrompt}"`;
222125
223056
  }
222126
223057
  async shouldConfirmExecute() {
222127
- if (this.config.getApprovalMode() === "auto-edit" /* AUTO_EDIT */) {
223058
+ if (this.config.getApprovalMode() === "auto-edit" /* AUTO_EDIT */ || this.config.getApprovalMode() === "plan" /* PLAN */) {
222128
223059
  return false;
222129
223060
  }
222130
223061
  const confirmationDetails = {
@@ -223028,7 +223959,7 @@ var init_web_search = __esm({
223028
223959
  return ` (Searching the web via ${provider})`;
223029
223960
  }
223030
223961
  async shouldConfirmExecute(_abortSignal) {
223031
- if (this.config.getApprovalMode() === "auto-edit" /* AUTO_EDIT */) {
223962
+ if (this.config.getApprovalMode() === "auto-edit" /* AUTO_EDIT */ || this.config.getApprovalMode() === "plan" /* PLAN */) {
223032
223963
  return false;
223033
223964
  }
223034
223965
  const confirmationDetails = {
@@ -226211,8 +227142,8 @@ var init_esm21 = __esm({
226211
227142
  }
226212
227143
  return this._userIgnored(path134, stats);
226213
227144
  }
226214
- _isntIgnored(path134, stat10) {
226215
- return !this._isIgnored(path134, stat10);
227145
+ _isntIgnored(path134, stat11) {
227146
+ return !this._isIgnored(path134, stat11);
226216
227147
  }
226217
227148
  /**
226218
227149
  * Provides a set of common helpers and properties relating to symlink handling.
@@ -226513,9 +227444,15 @@ async function loadSkillsFromDir(baseDir) {
226513
227444
  return [];
226514
227445
  }
226515
227446
  }
227447
+ function normalizeSkillFileContent(content) {
227448
+ let normalized2 = content.replace(/^\uFEFF/, "");
227449
+ normalized2 = normalized2.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
227450
+ return normalized2;
227451
+ }
226516
227452
  function parseSkillContent(content, filePath) {
226517
- const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
226518
- const match2 = content.match(frontmatterRegex);
227453
+ const normalizedContent = normalizeSkillFileContent(content);
227454
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---(?:\n|$)([\s\S]*)$/;
227455
+ const match2 = normalizedContent.match(frontmatterRegex);
226519
227456
  if (!match2) {
226520
227457
  throw new Error("Invalid format: missing YAML frontmatter");
226521
227458
  }
@@ -226596,6 +227533,7 @@ var init_skill_load = __esm({
226596
227533
  init_yaml_parser();
226597
227534
  SKILL_MANIFEST_FILE = "SKILL.md";
226598
227535
  __name(loadSkillsFromDir, "loadSkillsFromDir");
227536
+ __name(normalizeSkillFileContent, "normalizeSkillFileContent");
226599
227537
  __name(parseSkillContent, "parseSkillContent");
226600
227538
  __name(validateConfig, "validateConfig");
226601
227539
  }
@@ -226606,7 +227544,7 @@ import * as fs48 from "fs/promises";
226606
227544
  import * as fsSync3 from "fs";
226607
227545
  import * as path52 from "path";
226608
227546
  import * as os21 from "os";
226609
- function normalizeSkillFileContent(content) {
227547
+ function normalizeSkillFileContent2(content) {
226610
227548
  let normalized2 = content.replace(/^\uFEFF/, "");
226611
227549
  normalized2 = normalized2.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
226612
227550
  return normalized2;
@@ -226820,7 +227758,7 @@ var init_skill_manager = __esm({
226820
227758
  */
226821
227759
  parseSkillContent(content, filePath, level) {
226822
227760
  try {
226823
- const normalizedContent = normalizeSkillFileContent(content);
227761
+ const normalizedContent = normalizeSkillFileContent2(content);
226824
227762
  const frontmatterRegex = /^---\n([\s\S]*?)\n---(?:\n|$)([\s\S]*)$/;
226825
227763
  const match2 = normalizedContent.match(frontmatterRegex);
226826
227764
  if (!match2) {
@@ -226915,8 +227853,26 @@ var init_skill_manager = __esm({
226915
227853
  const entries = await fs48.readdir(baseDir, { withFileTypes: true });
226916
227854
  const skills = [];
226917
227855
  for (const entry of entries) {
226918
- if (!entry.isDirectory()) continue;
227856
+ const isDirectory = entry.isDirectory();
227857
+ const isSymlink = entry.isSymbolicLink();
227858
+ if (!isDirectory && !isSymlink) continue;
226919
227859
  const skillDir = path52.join(baseDir, entry.name);
227860
+ if (isSymlink) {
227861
+ try {
227862
+ const targetStat = await fs48.stat(skillDir);
227863
+ if (!targetStat.isDirectory()) {
227864
+ console.warn(
227865
+ `Skipping symlink ${entry.name} that does not point to a directory`
227866
+ );
227867
+ continue;
227868
+ }
227869
+ } catch (error2) {
227870
+ console.warn(
227871
+ `Skipping invalid symlink ${entry.name}: ${error2 instanceof Error ? error2.message : "Unknown error"}`
227872
+ );
227873
+ continue;
227874
+ }
227875
+ }
226920
227876
  const skillManifest = path52.join(skillDir, SKILL_MANIFEST_FILE2);
226921
227877
  try {
226922
227878
  await fs48.access(skillManifest);
@@ -227020,7 +227976,7 @@ var init_skill_manager = __esm({
227020
227976
  }
227021
227977
  }
227022
227978
  };
227023
- __name(normalizeSkillFileContent, "normalizeSkillFileContent");
227979
+ __name(normalizeSkillFileContent2, "normalizeSkillFileContent");
227024
227980
  }
227025
227981
  });
227026
227982
 
@@ -230469,16 +231425,16 @@ var init_list = __esm({
230469
231425
  let fd;
230470
231426
  try {
230471
231427
  fd = fs51.openSync(file, "r");
230472
- const stat10 = fs51.fstatSync(fd);
231428
+ const stat11 = fs51.fstatSync(fd);
230473
231429
  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
230474
- if (stat10.size < readSize) {
230475
- const buf = Buffer.allocUnsafe(stat10.size);
230476
- const read3 = fs51.readSync(fd, buf, 0, stat10.size, 0);
231430
+ if (stat11.size < readSize) {
231431
+ const buf = Buffer.allocUnsafe(stat11.size);
231432
+ const read3 = fs51.readSync(fd, buf, 0, stat11.size, 0);
230477
231433
  p2.end(read3 === buf.byteLength ? buf : buf.subarray(0, read3));
230478
231434
  } else {
230479
231435
  let pos2 = 0;
230480
231436
  const buf = Buffer.allocUnsafe(readSize);
230481
- while (pos2 < stat10.size) {
231437
+ while (pos2 < stat11.size) {
230482
231438
  const bytesRead = fs51.readSync(fd, buf, 0, readSize, pos2);
230483
231439
  if (bytesRead === 0)
230484
231440
  break;
@@ -230503,13 +231459,13 @@ var init_list = __esm({
230503
231459
  const p2 = new Promise((resolve33, reject) => {
230504
231460
  parse14.on("error", reject);
230505
231461
  parse14.on("end", resolve33);
230506
- fs51.stat(file, (er2, stat10) => {
231462
+ fs51.stat(file, (er2, stat11) => {
230507
231463
  if (er2) {
230508
231464
  reject(er2);
230509
231465
  } else {
230510
231466
  const stream2 = new ReadStream(file, {
230511
231467
  readSize,
230512
- size: stat10.size
231468
+ size: stat11.size
230513
231469
  });
230514
231470
  stream2.on("error", reject);
230515
231471
  stream2.pipe(parse14);
@@ -230725,21 +231681,21 @@ var init_write_entry = __esm({
230725
231681
  return super.emit(ev, ...data);
230726
231682
  }
230727
231683
  [LSTAT]() {
230728
- fs52.lstat(this.absolute, (er2, stat10) => {
231684
+ fs52.lstat(this.absolute, (er2, stat11) => {
230729
231685
  if (er2) {
230730
231686
  return this.emit("error", er2);
230731
231687
  }
230732
- this[ONLSTAT](stat10);
231688
+ this[ONLSTAT](stat11);
230733
231689
  });
230734
231690
  }
230735
- [ONLSTAT](stat10) {
230736
- this.statCache.set(this.absolute, stat10);
230737
- this.stat = stat10;
230738
- if (!stat10.isFile()) {
230739
- stat10.size = 0;
231691
+ [ONLSTAT](stat11) {
231692
+ this.statCache.set(this.absolute, stat11);
231693
+ this.stat = stat11;
231694
+ if (!stat11.isFile()) {
231695
+ stat11.size = 0;
230740
231696
  }
230741
- this.type = getType3(stat10);
230742
- this.emit("stat", stat10);
231697
+ this.type = getType3(stat11);
231698
+ this.emit("stat", stat11);
230743
231699
  this[PROCESS2]();
230744
231700
  }
230745
231701
  [PROCESS2]() {
@@ -231189,7 +232145,7 @@ var init_write_entry = __esm({
231189
232145
  return this;
231190
232146
  }
231191
232147
  };
231192
- getType3 = /* @__PURE__ */ __name((stat10) => stat10.isFile() ? "File" : stat10.isDirectory() ? "Directory" : stat10.isSymbolicLink() ? "SymbolicLink" : "Unsupported", "getType");
232148
+ getType3 = /* @__PURE__ */ __name((stat11) => stat11.isFile() ? "File" : stat11.isDirectory() ? "Directory" : stat11.isSymbolicLink() ? "SymbolicLink" : "Unsupported", "getType");
231193
232149
  }
231194
232150
  });
231195
232151
 
@@ -231789,21 +232745,21 @@ var init_pack = __esm({
231789
232745
  [STAT](job) {
231790
232746
  job.pending = true;
231791
232747
  this[JOBS] += 1;
231792
- const stat10 = this.follow ? "stat" : "lstat";
231793
- fs53[stat10](job.absolute, (er2, stat11) => {
232748
+ const stat11 = this.follow ? "stat" : "lstat";
232749
+ fs53[stat11](job.absolute, (er2, stat12) => {
231794
232750
  job.pending = false;
231795
232751
  this[JOBS] -= 1;
231796
232752
  if (er2) {
231797
232753
  this.emit("error", er2);
231798
232754
  } else {
231799
- this[ONSTAT](job, stat11);
232755
+ this[ONSTAT](job, stat12);
231800
232756
  }
231801
232757
  });
231802
232758
  }
231803
- [ONSTAT](job, stat10) {
231804
- this.statCache.set(job.absolute, stat10);
231805
- job.stat = stat10;
231806
- if (!this.filter(job.path, stat10)) {
232759
+ [ONSTAT](job, stat11) {
232760
+ this.statCache.set(job.absolute, stat11);
232761
+ job.stat = stat11;
232762
+ if (!this.filter(job.path, stat11)) {
231807
232763
  job.ignore = true;
231808
232764
  }
231809
232765
  this[PROCESS3]();
@@ -231985,8 +232941,8 @@ var init_pack = __esm({
231985
232941
  resume() {
231986
232942
  }
231987
232943
  [STAT](job) {
231988
- const stat10 = this.follow ? "statSync" : "lstatSync";
231989
- this[ONSTAT](job, fs53[stat10](job.absolute));
232944
+ const stat11 = this.follow ? "statSync" : "lstatSync";
232945
+ this[ONSTAT](job, fs53[stat11](job.absolute));
231990
232946
  }
231991
232947
  [READDIR](job) {
231992
232948
  this[ONREADDIR](job, fs53.readdirSync(job.absolute));
@@ -233286,11 +234242,11 @@ var init_extract = __esm({
233286
234242
  extractFileSync = /* @__PURE__ */ __name((opt) => {
233287
234243
  const u2 = new UnpackSync(opt);
233288
234244
  const file = opt.file;
233289
- const stat10 = fs58.statSync(file);
234245
+ const stat11 = fs58.statSync(file);
233290
234246
  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
233291
234247
  const stream2 = new ReadStreamSync(file, {
233292
234248
  readSize,
233293
- size: stat10.size
234249
+ size: stat11.size
233294
234250
  });
233295
234251
  stream2.pipe(u2);
233296
234252
  }, "extractFileSync");
@@ -233301,13 +234257,13 @@ var init_extract = __esm({
233301
234257
  const p2 = new Promise((resolve33, reject) => {
233302
234258
  u2.on("error", reject);
233303
234259
  u2.on("close", resolve33);
233304
- fs58.stat(file, (er2, stat10) => {
234260
+ fs58.stat(file, (er2, stat11) => {
233305
234261
  if (er2) {
233306
234262
  reject(er2);
233307
234263
  } else {
233308
234264
  const stream2 = new ReadStream(file, {
233309
234265
  readSize,
233310
- size: stat10.size
234266
+ size: stat11.size
233311
234267
  });
233312
234268
  stream2.on("error", reject);
233313
234269
  stream2.pipe(u2);
@@ -233552,9 +234508,9 @@ var init_update = __esm({
233552
234508
  if (!opt.mtimeCache) {
233553
234509
  opt.mtimeCache = /* @__PURE__ */ new Map();
233554
234510
  }
233555
- opt.filter = filter4 ? (path134, stat10) => filter4(path134, stat10) && !/* c8 ignore start */
233556
- ((opt.mtimeCache?.get(path134) ?? stat10.mtime ?? 0) > (stat10.mtime ?? 0)) : (path134, stat10) => !/* c8 ignore start */
233557
- ((opt.mtimeCache?.get(path134) ?? stat10.mtime ?? 0) > (stat10.mtime ?? 0));
234511
+ opt.filter = filter4 ? (path134, stat11) => filter4(path134, stat11) && !/* c8 ignore start */
234512
+ ((opt.mtimeCache?.get(path134) ?? stat11.mtime ?? 0) > (stat11.mtime ?? 0)) : (path134, stat11) => !/* c8 ignore start */
234513
+ ((opt.mtimeCache?.get(path134) ?? stat11.mtime ?? 0) > (stat11.mtime ?? 0));
233558
234514
  }, "mtimeFilter");
233559
234515
  }
233560
234516
  });
@@ -238339,8 +239295,8 @@ async function collectResources(resourcePaths, pluginRoot, destDir) {
238339
239295
  console.warn(`Resource path not found: ${resolvedPath}`);
238340
239296
  continue;
238341
239297
  }
238342
- const stat10 = fs63.statSync(resolvedPath);
238343
- if (stat10.isDirectory()) {
239298
+ const stat11 = fs63.statSync(resolvedPath);
239299
+ if (stat11.isDirectory()) {
238344
239300
  const dirName = path65.basename(resolvedPath);
238345
239301
  const parentDir = path65.dirname(resolvedPath);
238346
239302
  if (dirName === destFolderName && parentDir === pluginRoot) {
@@ -249145,12 +250101,6 @@ var init_config3 = __esm({
249145
250101
  getSessionId() {
249146
250102
  return this.sessionId;
249147
250103
  }
249148
- /**
249149
- * Releases resources owned by the config instance.
249150
- */
249151
- async shutdown() {
249152
- this.skillManager?.stopWatching();
249153
- }
249154
250104
  /**
249155
250105
  * Starts a new session and resets session-scoped services.
249156
250106
  */
@@ -249291,6 +250241,24 @@ var init_config3 = __esm({
249291
250241
  getToolRegistry() {
249292
250242
  return this.toolRegistry;
249293
250243
  }
250244
+ /**
250245
+ * Shuts down the Config and releases all resources.
250246
+ * This method is idempotent and safe to call multiple times.
250247
+ * It handles the case where initialization was not completed.
250248
+ */
250249
+ async shutdown() {
250250
+ if (!this.initialized) {
250251
+ return;
250252
+ }
250253
+ try {
250254
+ this.skillManager?.stopWatching();
250255
+ if (this.toolRegistry) {
250256
+ await this.toolRegistry.stop();
250257
+ }
250258
+ } catch (error2) {
250259
+ console.error("Error during Config shutdown:", error2);
250260
+ }
250261
+ }
249294
250262
  getPromptRegistry() {
249295
250263
  return this.promptRegistry;
249296
250264
  }
@@ -252778,12 +253746,12 @@ var require_resolve_symlink = __commonJS({
252778
253746
  fs_1.default.realpath(path134, (error2, resolvedPath) => {
252779
253747
  if (error2)
252780
253748
  return queue.dequeue(suppressErrors ? null : error2, state);
252781
- fs_1.default.stat(resolvedPath, (error3, stat10) => {
253749
+ fs_1.default.stat(resolvedPath, (error3, stat11) => {
252782
253750
  if (error3)
252783
253751
  return queue.dequeue(suppressErrors ? null : error3, state);
252784
- if (stat10.isDirectory() && isRecursive(path134, resolvedPath, state))
253752
+ if (stat11.isDirectory() && isRecursive(path134, resolvedPath, state))
252785
253753
  return queue.dequeue(null, state);
252786
- callback(stat10, resolvedPath);
253754
+ callback(stat11, resolvedPath);
252787
253755
  queue.dequeue(null, state);
252788
253756
  });
252789
253757
  });
@@ -252793,10 +253761,10 @@ var require_resolve_symlink = __commonJS({
252793
253761
  queue.enqueue();
252794
253762
  try {
252795
253763
  const resolvedPath = fs_1.default.realpathSync(path134);
252796
- const stat10 = fs_1.default.statSync(resolvedPath);
252797
- if (stat10.isDirectory() && isRecursive(path134, resolvedPath, state))
253764
+ const stat11 = fs_1.default.statSync(resolvedPath);
253765
+ if (stat11.isDirectory() && isRecursive(path134, resolvedPath, state))
252798
253766
  return;
252799
- callback(stat10, resolvedPath);
253767
+ callback(stat11, resolvedPath);
252800
253768
  } catch (e4) {
252801
253769
  if (!suppressErrors)
252802
253770
  throw e4;
@@ -253115,8 +254083,8 @@ var require_walker = __commonJS({
253115
254083
  this.walkDirectory(this.state, path134, path134, depth - 1, this.walk);
253116
254084
  } else if (this.resolveSymlink && entry.isSymbolicLink()) {
253117
254085
  let path134 = joinPath.joinPathWithBasePath(entry.name, directoryPath);
253118
- this.resolveSymlink(path134, this.state, (stat10, resolvedPath) => {
253119
- if (stat10.isDirectory()) {
254086
+ this.resolveSymlink(path134, this.state, (stat11, resolvedPath) => {
254087
+ if (stat11.isDirectory()) {
253120
254088
  resolvedPath = (0, utils_1.normalizePath)(resolvedPath, this.state.options);
253121
254089
  if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path134 + pathSeparator))
253122
254090
  return;
@@ -255091,7 +256059,7 @@ var init_skills = __esm({
255091
256059
  import * as fs74 from "node:fs";
255092
256060
  import * as path79 from "node:path";
255093
256061
  import * as https5 from "node:https";
255094
- import { stat as stat6 } from "node:fs/promises";
256062
+ import { stat as stat7 } from "node:fs/promises";
255095
256063
  function parseSourceAndPluginName(source2) {
255096
256064
  const urlSchemes = ["http://", "https://", "git@", "sso://"];
255097
256065
  let repoEndIndex = source2.length;
@@ -255220,7 +256188,7 @@ async function parseInstallSource(source2) {
255220
256188
  }
255221
256189
  } else {
255222
256190
  try {
255223
- await stat6(repo);
256191
+ await stat7(repo);
255224
256192
  installMetadata = {
255225
256193
  source: repo,
255226
256194
  type: "local",
@@ -259110,8 +260078,8 @@ var init_git_commit = __esm({
259110
260078
  "packages/core/src/generated/git-commit.ts"() {
259111
260079
  "use strict";
259112
260080
  init_esbuild_shims();
259113
- GIT_COMMIT_INFO = "6bc19dab8";
259114
- CLI_VERSION = "0.2.3-alpha.2";
260081
+ GIT_COMMIT_INFO = "1ebbd0090";
260082
+ CLI_VERSION = "0.2.3-alpha.4";
259115
260083
  }
259116
260084
  });
259117
260085
 
@@ -359905,7 +360873,7 @@ __name(getPackageJson, "getPackageJson");
359905
360873
  // packages/cli/src/utils/version.ts
359906
360874
  async function getCliVersion() {
359907
360875
  const pkgJson = await getPackageJson();
359908
- return "0.2.3-alpha.2";
360876
+ return "0.2.3-alpha.4";
359909
360877
  }
359910
360878
  __name(getCliVersion, "getCliVersion");
359911
360879
 
@@ -367635,7 +368603,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
367635
368603
 
367636
368604
  // packages/cli/src/generated/git-commit.ts
367637
368605
  init_esbuild_shims();
367638
- var GIT_COMMIT_INFO2 = "6bc19dab8";
368606
+ var GIT_COMMIT_INFO2 = "1ebbd0090";
367639
368607
 
367640
368608
  // packages/cli/src/utils/systemInfo.ts
367641
368609
  async function getNpmVersion() {
@@ -377402,6 +378370,161 @@ function parseAllAtCommands(query) {
377402
378370
  );
377403
378371
  }
377404
378372
  __name(parseAllAtCommands, "parseAllAtCommands");
378373
+ function getConfiguredMcpServerNames(config2) {
378374
+ const names = new Set(Object.keys(config2.getMcpServers() ?? {}));
378375
+ if (config2.getMcpServerCommand()) {
378376
+ names.add("mcp");
378377
+ }
378378
+ return names;
378379
+ }
378380
+ __name(getConfiguredMcpServerNames, "getConfiguredMcpServerNames");
378381
+ function normalizeMcpResourceUri(serverName, resource) {
378382
+ if (resource.includes("://")) {
378383
+ return resource;
378384
+ }
378385
+ const cleaned = resource.startsWith("/") ? resource.slice(1) : resource;
378386
+ return `${serverName}://${cleaned}`;
378387
+ }
378388
+ __name(normalizeMcpResourceUri, "normalizeMcpResourceUri");
378389
+ function splitLeadingToken(text) {
378390
+ let i3 = 0;
378391
+ while (i3 < text.length && /\s/.test(text[i3])) {
378392
+ i3++;
378393
+ }
378394
+ if (i3 >= text.length) {
378395
+ return null;
378396
+ }
378397
+ let token2 = "";
378398
+ let inEscape = false;
378399
+ while (i3 < text.length) {
378400
+ const char = text[i3];
378401
+ if (inEscape) {
378402
+ token2 += char;
378403
+ inEscape = false;
378404
+ i3++;
378405
+ continue;
378406
+ }
378407
+ if (char === "\\") {
378408
+ inEscape = true;
378409
+ i3++;
378410
+ continue;
378411
+ }
378412
+ if (/[,\s;!?()[\]{}]/.test(char)) {
378413
+ break;
378414
+ }
378415
+ if (char === ".") {
378416
+ const nextChar = i3 + 1 < text.length ? text[i3 + 1] : "";
378417
+ if (nextChar === "" || /\s/.test(nextChar)) {
378418
+ break;
378419
+ }
378420
+ }
378421
+ token2 += char;
378422
+ i3++;
378423
+ }
378424
+ if (!token2) {
378425
+ return null;
378426
+ }
378427
+ return { token: token2, rest: text.slice(i3) };
378428
+ }
378429
+ __name(splitLeadingToken, "splitLeadingToken");
378430
+ function extractMcpResourceAtReferences(parts, config2) {
378431
+ const configuredServers = getConfiguredMcpServerNames(config2);
378432
+ const refs = [];
378433
+ const merged = [];
378434
+ for (let i3 = 0; i3 < parts.length; i3++) {
378435
+ const part = parts[i3];
378436
+ if (part.type !== "atPath") {
378437
+ merged.push(part);
378438
+ continue;
378439
+ }
378440
+ const atText = part.content;
378441
+ const colonIndex = atText.indexOf(":");
378442
+ if (!atText.startsWith("@") || colonIndex <= 1) {
378443
+ merged.push(part);
378444
+ continue;
378445
+ }
378446
+ const serverName = atText.slice(1, colonIndex);
378447
+ if (!configuredServers.has(serverName)) {
378448
+ merged.push(part);
378449
+ continue;
378450
+ }
378451
+ let resource = atText.slice(colonIndex + 1);
378452
+ if (!resource) {
378453
+ const next = parts[i3 + 1];
378454
+ if (next?.type === "text") {
378455
+ const tokenInfo = splitLeadingToken(next.content);
378456
+ if (tokenInfo) {
378457
+ resource = tokenInfo.token;
378458
+ const remainingText = tokenInfo.rest;
378459
+ parts[i3 + 1] = { type: "text", content: remainingText };
378460
+ }
378461
+ }
378462
+ }
378463
+ if (!resource) {
378464
+ merged.push({ type: "text", content: atText });
378465
+ continue;
378466
+ }
378467
+ const normalizedResource = resource.includes("://") ? resource : resource.startsWith("/") ? resource.slice(1) : resource;
378468
+ const normalizedAtCommand = `@${serverName}:${normalizedResource}`;
378469
+ refs.push({
378470
+ atCommand: normalizedAtCommand,
378471
+ serverName,
378472
+ uri: normalizeMcpResourceUri(serverName, normalizedResource)
378473
+ });
378474
+ merged.push({ type: "atPath", content: normalizedAtCommand });
378475
+ }
378476
+ return {
378477
+ parts: merged.filter(
378478
+ (p2) => !(p2.type === "text" && p2.content.trim() === "")
378479
+ ),
378480
+ refs
378481
+ };
378482
+ }
378483
+ __name(extractMcpResourceAtReferences, "extractMcpResourceAtReferences");
378484
+ function formatMcpResourceContents(raw2, limits) {
378485
+ if (!raw2 || typeof raw2 !== "object") {
378486
+ return "[Error: Invalid MCP resource response]";
378487
+ }
378488
+ const contents = raw2.contents;
378489
+ if (!Array.isArray(contents)) {
378490
+ return "[Error: Invalid MCP resource response]";
378491
+ }
378492
+ const parts = [];
378493
+ for (const item of contents) {
378494
+ if (!item || typeof item !== "object") {
378495
+ continue;
378496
+ }
378497
+ const text = item.text;
378498
+ const blob = item.blob;
378499
+ const mimeType = item.mimeType;
378500
+ if (typeof text === "string") {
378501
+ parts.push(text);
378502
+ continue;
378503
+ }
378504
+ if (typeof blob === "string") {
378505
+ const mimeTypeLabel = typeof mimeType === "string" ? mimeType : "application/octet-stream";
378506
+ parts.push(
378507
+ `[Binary MCP resource omitted (mimeType: ${mimeTypeLabel}, bytes: ${blob.length})]`
378508
+ );
378509
+ }
378510
+ }
378511
+ let combined = parts.join("\n\n");
378512
+ const maxLines = limits.maxLinesPerResource;
378513
+ if (Number.isFinite(maxLines)) {
378514
+ const lines = combined.split("\n");
378515
+ if (lines.length > maxLines) {
378516
+ combined = `${lines.slice(0, maxLines).join("\n")}
378517
+ [truncated]`;
378518
+ }
378519
+ }
378520
+ const maxChars = limits.maxCharsPerResource;
378521
+ if (Number.isFinite(maxChars) && combined.length > maxChars) {
378522
+ combined = `${combined.slice(0, maxChars)}
378523
+ [truncated]`;
378524
+ }
378525
+ return combined;
378526
+ }
378527
+ __name(formatMcpResourceContents, "formatMcpResourceContents");
377405
378528
  async function handleAtCommand({
377406
378529
  query,
377407
378530
  config: config2,
@@ -377410,10 +378533,15 @@ async function handleAtCommand({
377410
378533
  messageId: userMessageTimestamp,
377411
378534
  signal
377412
378535
  }) {
377413
- const commandParts = parseAllAtCommands(query);
378536
+ const parsedParts = parseAllAtCommands(query);
378537
+ const { parts: commandParts, refs: mcpResourceRefs } = extractMcpResourceAtReferences(parsedParts, config2);
378538
+ const mcpAtCommands = new Set(mcpResourceRefs.map((r5) => r5.atCommand));
377414
378539
  const atPathCommandParts = commandParts.filter(
377415
378540
  (part) => part.type === "atPath"
377416
378541
  );
378542
+ const fileAtPathCommandParts = atPathCommandParts.filter(
378543
+ (part) => !mcpAtCommands.has(part.content)
378544
+ );
377417
378545
  if (atPathCommandParts.length === 0) {
377418
378546
  return { processedQuery: [{ text: query }], shouldProceed: true };
377419
378547
  }
@@ -377430,14 +378558,7 @@ async function handleAtCommand({
377430
378558
  const toolRegistry = config2.getToolRegistry();
377431
378559
  const readManyFilesTool = toolRegistry.getTool("read_many_files");
377432
378560
  const globTool = toolRegistry.getTool("glob");
377433
- if (!readManyFilesTool) {
377434
- addItem(
377435
- { type: "error", text: "Error: read_many_files tool not found." },
377436
- userMessageTimestamp
377437
- );
377438
- return { processedQuery: null, shouldProceed: false };
377439
- }
377440
- for (const atPathPart of atPathCommandParts) {
378561
+ for (const atPathPart of fileAtPathCommandParts) {
377441
378562
  const originalAtPath = atPathPart.content;
377442
378563
  if (originalAtPath === "@") {
377443
378564
  onDebugMessage(
@@ -377597,7 +378718,7 @@ ${messages.join("\n")}`;
377597
378718
  console.log(message);
377598
378719
  onDebugMessage(message);
377599
378720
  }
377600
- if (pathSpecsToRead.length === 0) {
378721
+ if (pathSpecsToRead.length === 0 && mcpResourceRefs.length === 0) {
377601
378722
  onDebugMessage("No valid file paths found in @ commands to read.");
377602
378723
  if (initialQueryText === "@" && query.trim() === "@") {
377603
378724
  return { processedQuery: [{ text: query }], shouldProceed: true };
@@ -377610,76 +378731,146 @@ ${messages.join("\n")}`;
377610
378731
  };
377611
378732
  }
377612
378733
  const processedQueryParts = [{ text: initialQueryText }];
377613
- const toolArgs = {
377614
- paths: pathSpecsToRead,
377615
- file_filtering_options: {
377616
- respect_git_ignore: respectFileIgnore.respectGitIgnore,
377617
- respect_rdmind_ignore: respectFileIgnore.respectRdmindIgnore
378734
+ const toolDisplays = [];
378735
+ if (pathSpecsToRead.length > 0) {
378736
+ if (!readManyFilesTool) {
378737
+ addItem(
378738
+ { type: "error", text: "Error: read_many_files tool not found." },
378739
+ userMessageTimestamp
378740
+ );
378741
+ return { processedQuery: null, shouldProceed: false };
377618
378742
  }
377619
- // Use configuration setting
377620
- };
377621
- let toolCallDisplay;
377622
- let invocation = void 0;
377623
- try {
377624
- invocation = readManyFilesTool.build(toolArgs);
377625
- const result = await invocation.execute(signal);
377626
- toolCallDisplay = {
377627
- callId: `client-read-${userMessageTimestamp}`,
377628
- name: readManyFilesTool.displayName,
377629
- description: invocation.getDescription(),
377630
- status: "Success" /* Success */,
377631
- resultDisplay: result.returnDisplay || `Successfully read: ${contentLabelsForDisplay.join(", ")}`,
377632
- confirmationDetails: void 0
377633
- };
377634
- if (Array.isArray(result.llmContent)) {
377635
- const fileContentRegex = /^--- (.*?) ---\n\n([\s\S]*?)\n\n$/;
377636
- processedQueryParts.push({
377637
- text: "\n--- Content from referenced files ---"
378743
+ const toolArgs = {
378744
+ paths: pathSpecsToRead,
378745
+ file_filtering_options: {
378746
+ respect_git_ignore: respectFileIgnore.respectGitIgnore,
378747
+ respect_rdmind_ignore: respectFileIgnore.respectRdmindIgnore
378748
+ }
378749
+ // Use configuration setting
378750
+ };
378751
+ let invocation = void 0;
378752
+ try {
378753
+ invocation = readManyFilesTool.build(toolArgs);
378754
+ const result = await invocation.execute(signal);
378755
+ toolDisplays.push({
378756
+ callId: `client-read-${userMessageTimestamp}`,
378757
+ name: readManyFilesTool.displayName,
378758
+ description: invocation.getDescription(),
378759
+ status: "Success" /* Success */,
378760
+ resultDisplay: result.returnDisplay || `Successfully read: ${contentLabelsForDisplay.join(", ")}`,
378761
+ confirmationDetails: void 0
377638
378762
  });
377639
- for (const part of result.llmContent) {
377640
- if (typeof part === "string") {
377641
- const match2 = fileContentRegex.exec(part);
377642
- if (match2) {
377643
- const filePathSpecInContent = match2[1];
377644
- const fileActualContent = match2[2].trim();
377645
- processedQueryParts.push({
377646
- text: `
378763
+ if (Array.isArray(result.llmContent)) {
378764
+ const fileContentRegex = /^--- (.*?) ---\n\n([\s\S]*?)\n\n$/;
378765
+ processedQueryParts.push({
378766
+ text: "\n--- Content from referenced files ---"
378767
+ });
378768
+ for (const part of result.llmContent) {
378769
+ if (typeof part === "string") {
378770
+ const match2 = fileContentRegex.exec(part);
378771
+ if (match2) {
378772
+ const filePathSpecInContent = match2[1];
378773
+ const fileActualContent = match2[2].trim();
378774
+ processedQueryParts.push({
378775
+ text: `
377647
378776
  Content from @${filePathSpecInContent}:
377648
378777
  `
377649
- });
377650
- processedQueryParts.push({ text: fileActualContent });
378778
+ });
378779
+ processedQueryParts.push({ text: fileActualContent });
378780
+ } else {
378781
+ processedQueryParts.push({ text: part });
378782
+ }
377651
378783
  } else {
377652
- processedQueryParts.push({ text: part });
378784
+ processedQueryParts.push(part);
377653
378785
  }
377654
- } else {
377655
- processedQueryParts.push(part);
377656
378786
  }
378787
+ } else {
378788
+ onDebugMessage(
378789
+ "read_many_files tool returned no content or empty content."
378790
+ );
377657
378791
  }
377658
- } else {
377659
- onDebugMessage(
377660
- "read_many_files tool returned no content or empty content."
378792
+ } catch (error2) {
378793
+ toolDisplays.push({
378794
+ callId: `client-read-${userMessageTimestamp}`,
378795
+ name: readManyFilesTool.displayName,
378796
+ description: invocation?.getDescription() ?? "Error attempting to execute tool to read files",
378797
+ status: "Error" /* Error */,
378798
+ resultDisplay: `Error reading files (${contentLabelsForDisplay.join(", ")}): ${getErrorMessage(error2)}`,
378799
+ confirmationDetails: void 0
378800
+ });
378801
+ addItem(
378802
+ { type: "tool_group", tools: toolDisplays },
378803
+ userMessageTimestamp
377661
378804
  );
378805
+ return { processedQuery: null, shouldProceed: false };
377662
378806
  }
378807
+ }
378808
+ if (mcpResourceRefs.length > 0) {
378809
+ const totalCharLimit = config2.getTruncateToolOutputThreshold();
378810
+ const totalLineLimit = config2.getTruncateToolOutputLines();
378811
+ const maxCharsPerResource = Number.isFinite(totalCharLimit) ? Math.floor(totalCharLimit / Math.max(1, mcpResourceRefs.length)) : Number.POSITIVE_INFINITY;
378812
+ const maxLinesPerResource = Number.isFinite(totalLineLimit) ? Math.floor(totalLineLimit / Math.max(1, mcpResourceRefs.length)) : Number.POSITIVE_INFINITY;
378813
+ processedQueryParts.push({
378814
+ text: "\n--- Content from referenced MCP resources ---"
378815
+ });
378816
+ for (let i3 = 0; i3 < mcpResourceRefs.length; i3++) {
378817
+ const ref = mcpResourceRefs[i3];
378818
+ let resourceResult;
378819
+ try {
378820
+ if (signal.aborted) {
378821
+ const error2 = new Error("MCP resource read aborted");
378822
+ error2.name = "AbortError";
378823
+ throw error2;
378824
+ }
378825
+ resourceResult = await toolRegistry.readMcpResource(
378826
+ ref.serverName,
378827
+ ref.uri,
378828
+ { signal }
378829
+ );
378830
+ toolDisplays.push({
378831
+ callId: `client-mcp-resource-${userMessageTimestamp}-${i3}`,
378832
+ name: "McpResourceRead",
378833
+ description: `Read MCP resource ${ref.uri} (server: ${ref.serverName})`,
378834
+ status: "Success" /* Success */,
378835
+ resultDisplay: `Read: ${ref.uri}`,
378836
+ confirmationDetails: void 0
378837
+ });
378838
+ } catch (error2) {
378839
+ toolDisplays.push({
378840
+ callId: `client-mcp-resource-${userMessageTimestamp}-${i3}`,
378841
+ name: "McpResourceRead",
378842
+ description: `Read MCP resource ${ref.uri} (server: ${ref.serverName})`,
378843
+ status: "Error" /* Error */,
378844
+ resultDisplay: `Error reading MCP resource (${ref.uri}): ${getErrorMessage(error2)}`,
378845
+ confirmationDetails: void 0
378846
+ });
378847
+ addItem(
378848
+ { type: "tool_group", tools: toolDisplays },
378849
+ userMessageTimestamp
378850
+ );
378851
+ return { processedQuery: null, shouldProceed: false };
378852
+ }
378853
+ processedQueryParts.push({
378854
+ text: `
378855
+ Content from ${ref.atCommand}:
378856
+ `
378857
+ });
378858
+ processedQueryParts.push({
378859
+ text: formatMcpResourceContents(resourceResult, {
378860
+ maxCharsPerResource,
378861
+ maxLinesPerResource
378862
+ })
378863
+ });
378864
+ }
378865
+ processedQueryParts.push({ text: "\n--- End of MCP resource content ---" });
378866
+ }
378867
+ if (toolDisplays.length > 0) {
377663
378868
  addItem(
377664
- { type: "tool_group", tools: [toolCallDisplay] },
377665
- userMessageTimestamp
377666
- );
377667
- return { processedQuery: processedQueryParts, shouldProceed: true };
377668
- } catch (error2) {
377669
- toolCallDisplay = {
377670
- callId: `client-read-${userMessageTimestamp}`,
377671
- name: readManyFilesTool.displayName,
377672
- description: invocation?.getDescription() ?? "Error attempting to execute tool to read files",
377673
- status: "Error" /* Error */,
377674
- resultDisplay: `Error reading files (${contentLabelsForDisplay.join(", ")}): ${getErrorMessage(error2)}`,
377675
- confirmationDetails: void 0
377676
- };
377677
- addItem(
377678
- { type: "tool_group", tools: [toolCallDisplay] },
378869
+ { type: "tool_group", tools: toolDisplays },
377679
378870
  userMessageTimestamp
377680
378871
  );
377681
- return { processedQuery: null, shouldProceed: false };
377682
378872
  }
378873
+ return { processedQuery: processedQueryParts, shouldProceed: true };
377683
378874
  }
377684
378875
  __name(handleAtCommand, "handleAtCommand");
377685
378876
 
@@ -407437,6 +408628,13 @@ var XHS_SSO_MODELS = [
407437
408628
  baseUrl: "https://runway.devops.xiaohongshu.com/openai/moonshot/v1",
407438
408629
  contextWindow: "256K",
407439
408630
  description: "\u5728 Agent\u3001\u4EE3\u7801\u3001\u89C6\u89C9\u7406\u89E3\u53CA\u4E00\u7CFB\u5217\u901A\u7528\u667A\u80FD\u4EFB\u52A1\u4E0A\u53D6\u5F97\u5F00\u6E90 SoTA \u8868\u73B0"
408631
+ },
408632
+ {
408633
+ id: "claude-opus-4-5@20251101",
408634
+ displayName: "Claude Opus 4.5",
408635
+ baseUrl: "https://runway.devops.rednote.life/openai/google/anthropic/v1",
408636
+ contextWindow: "200K",
408637
+ description: "Anthropic \u6700\u5F3A\u5927\u7684\u6A21\u578B\uFF0C\u64C5\u957F\u590D\u6742\u63A8\u7406\u548C\u4EE3\u7801\u751F\u6210"
407440
408638
  }
407441
408639
  ];
407442
408640
 
@@ -426065,7 +427263,7 @@ var GeminiAgent = class {
426065
427263
  name: APPROVAL_MODE_INFO[mode].name,
426066
427264
  description: APPROVAL_MODE_INFO[mode].description
426067
427265
  }));
426068
- const version2 = "0.2.3-alpha.2";
427266
+ const version2 = "0.2.3-alpha.4";
426069
427267
  return {
426070
427268
  protocolVersion: PROTOCOL_VERSION,
426071
427269
  agentInfo: {