@rdmind/rdmind 0.1.3-alpha.6 → 0.1.4-alpha.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 +803 -150
  2. package/package.json +2 -2
package/cli.js CHANGED
@@ -156760,10 +156760,8 @@ var init_deepseek = __esm({
156760
156760
  ...baseRequest,
156761
156761
  messages,
156762
156762
  /* @ts-expect-error DeepSeek exclusive */
156763
- extra_body: {
156764
- chat_template_kwargs: {
156765
- thinking: true
156766
- }
156763
+ chat_template_kwargs: {
156764
+ thinking: true
156767
156765
  }
156768
156766
  };
156769
156767
  }
@@ -157978,6 +157976,20 @@ var init_converter2 = __esm({
157978
157976
  resetStreamingToolCalls() {
157979
157977
  this.streamingToolCallParser.reset();
157980
157978
  }
157979
+ /**
157980
+ * Unescape newline sequences in reasoning content from Gemini models.
157981
+ * Gemini sometimes returns reasoning_content with escaped newlines (\\n)
157982
+ * that need to be converted to actual newline characters.
157983
+ *
157984
+ * @param text The text with potential escaped newlines
157985
+ * @returns The text with escaped newlines converted to actual newlines
157986
+ */
157987
+ unescapeReasoningContent(text) {
157988
+ if (!text) return text;
157989
+ let result = text.replace(/\\n/g, "\n");
157990
+ result = result.replace(/\n{4,}/g, "\n\n\n");
157991
+ return result;
157992
+ }
157981
157993
  /**
157982
157994
  * Convert Gemini tool parameters to OpenAI JSON Schema format
157983
157995
  */
@@ -158330,7 +158342,8 @@ var init_converter2 = __esm({
158330
158342
  const parts = [];
158331
158343
  const reasoningText = choice2.message.reasoning_content;
158332
158344
  if (reasoningText) {
158333
- parts.push({ text: reasoningText, thought: true });
158345
+ const unescapedReasoningText = this.unescapeReasoningContent(reasoningText);
158346
+ parts.push({ text: unescapedReasoningText, thought: true });
158334
158347
  }
158335
158348
  if (choice2.message.content) {
158336
158349
  parts.push({ text: choice2.message.content });
@@ -158401,7 +158414,8 @@ var init_converter2 = __esm({
158401
158414
  const parts = [];
158402
158415
  const reasoningText = choice2.delta.reasoning_content;
158403
158416
  if (reasoningText) {
158404
- parts.push({ text: reasoningText, thought: true });
158417
+ const unescapedReasoningText = this.unescapeReasoningContent(reasoningText);
158418
+ parts.push({ text: unescapedReasoningText, thought: true });
158405
158419
  }
158406
158420
  if (choice2.delta?.content) {
158407
158421
  if (typeof choice2.delta.content === "string") {
@@ -160787,7 +160801,7 @@ function createContentGeneratorConfig(config2, authType, generationConfig) {
160787
160801
  };
160788
160802
  }
160789
160803
  async function createContentGenerator(config2, gcConfig, isInitialAuth) {
160790
- const version3 = "0.1.3-alpha.6";
160804
+ const version3 = "0.1.4-alpha.0";
160791
160805
  const userAgent2 = `QwenCode/${version3} (${process.platform}; ${process.arch})`;
160792
160806
  const baseHeaders = {
160793
160807
  "User-Agent": userAgent2
@@ -214581,6 +214595,119 @@ var init_sa_impersonation_provider = __esm({
214581
214595
  }
214582
214596
  });
214583
214597
 
214598
+ // packages/core/src/tools/sdk-control-client-transport.ts
214599
+ var SdkControlClientTransport;
214600
+ var init_sdk_control_client_transport = __esm({
214601
+ "packages/core/src/tools/sdk-control-client-transport.ts"() {
214602
+ "use strict";
214603
+ init_esbuild_shims();
214604
+ SdkControlClientTransport = class {
214605
+ static {
214606
+ __name(this, "SdkControlClientTransport");
214607
+ }
214608
+ serverName;
214609
+ sendMcpMessage;
214610
+ debugMode;
214611
+ started = false;
214612
+ // Transport interface callbacks
214613
+ onmessage;
214614
+ onerror;
214615
+ onclose;
214616
+ constructor(options2) {
214617
+ this.serverName = options2.serverName;
214618
+ this.sendMcpMessage = options2.sendMcpMessage;
214619
+ this.debugMode = options2.debugMode ?? false;
214620
+ }
214621
+ /**
214622
+ * Start the transport
214623
+ * For SDK transport, this just marks it as ready - no subprocess to spawn
214624
+ */
214625
+ async start() {
214626
+ if (this.started) {
214627
+ return;
214628
+ }
214629
+ this.started = true;
214630
+ if (this.debugMode) {
214631
+ console.error(
214632
+ `[SdkControlClientTransport] Started for server '${this.serverName}'`
214633
+ );
214634
+ }
214635
+ }
214636
+ /**
214637
+ * Send a message to the SDK MCP server via control plane
214638
+ *
214639
+ * Routes the message through the control plane and delivers
214640
+ * the response via onmessage callback.
214641
+ */
214642
+ async send(message) {
214643
+ if (!this.started) {
214644
+ throw new Error(
214645
+ `SdkControlClientTransport (${this.serverName}) not started. Call start() first.`
214646
+ );
214647
+ }
214648
+ if (this.debugMode) {
214649
+ console.error(
214650
+ `[SdkControlClientTransport] Sending message to '${this.serverName}':`,
214651
+ JSON.stringify(message)
214652
+ );
214653
+ }
214654
+ try {
214655
+ const response = await this.sendMcpMessage(this.serverName, message);
214656
+ if (this.debugMode) {
214657
+ console.error(
214658
+ `[SdkControlClientTransport] Received response from '${this.serverName}':`,
214659
+ JSON.stringify(response)
214660
+ );
214661
+ }
214662
+ if (this.onmessage) {
214663
+ this.onmessage(response);
214664
+ }
214665
+ } catch (error2) {
214666
+ if (this.debugMode) {
214667
+ console.error(
214668
+ `[SdkControlClientTransport] Error sending to '${this.serverName}':`,
214669
+ error2
214670
+ );
214671
+ }
214672
+ if (this.onerror) {
214673
+ this.onerror(error2 instanceof Error ? error2 : new Error(String(error2)));
214674
+ }
214675
+ throw error2;
214676
+ }
214677
+ }
214678
+ /**
214679
+ * Close the transport
214680
+ */
214681
+ async close() {
214682
+ if (!this.started) {
214683
+ return;
214684
+ }
214685
+ this.started = false;
214686
+ if (this.debugMode) {
214687
+ console.error(
214688
+ `[SdkControlClientTransport] Closed for server '${this.serverName}'`
214689
+ );
214690
+ }
214691
+ if (this.onclose) {
214692
+ this.onclose();
214693
+ }
214694
+ }
214695
+ /**
214696
+ * Check if transport is started
214697
+ */
214698
+ isStarted() {
214699
+ return this.started;
214700
+ }
214701
+ /**
214702
+ * Get server name
214703
+ */
214704
+ getServerName() {
214705
+ return this.serverName;
214706
+ }
214707
+ };
214708
+ }
214709
+ });
214710
+
214584
214711
  // packages/core/src/utils/secure-browser-launcher.ts
214585
214712
  import { execFile as execFile8 } from "node:child_process";
214586
214713
  import { promisify as promisify7 } from "node:util";
@@ -215932,7 +216059,7 @@ function populateMcpServerCommand(mcpServers, mcpServerCommand) {
215932
216059
  }
215933
216060
  return mcpServers;
215934
216061
  }
215935
- async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext, cliConfig) {
216062
+ async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext, cliConfig, sendSdkMcpMessage) {
215936
216063
  updateMCPServerStatus(mcpServerName, "connecting" /* CONNECTING */);
215937
216064
  let mcpClient;
215938
216065
  try {
@@ -215940,7 +216067,8 @@ async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry,
215940
216067
  mcpServerName,
215941
216068
  mcpServerConfig,
215942
216069
  debugMode,
215943
- workspaceContext
216070
+ workspaceContext,
216071
+ sendSdkMcpMessage
215944
216072
  );
215945
216073
  mcpClient.onerror = (error2) => {
215946
216074
  console.error(`MCP ERROR (${mcpServerName}):`, error2.toString());
@@ -216074,7 +216202,7 @@ async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, promptParam
216074
216202
  function hasNetworkTransport(config2) {
216075
216203
  return !!(config2.url || config2.httpUrl);
216076
216204
  }
216077
- async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext) {
216205
+ async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext, sendSdkMcpMessage) {
216078
216206
  const mcpClient = new Client({
216079
216207
  name: "qwen-code-mcp-client",
216080
216208
  version: "0.0.1"
@@ -216116,7 +216244,8 @@ async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, wor
216116
216244
  const transport = await createTransport(
216117
216245
  mcpServerName,
216118
216246
  mcpServerConfig,
216119
- debugMode
216247
+ debugMode,
216248
+ sendSdkMcpMessage
216120
216249
  );
216121
216250
  try {
216122
216251
  await mcpClient.connect(transport, {
@@ -216416,7 +216545,19 @@ async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, wor
216416
216545
  }
216417
216546
  }
216418
216547
  }
216419
- async function createTransport(mcpServerName, mcpServerConfig, debugMode) {
216548
+ async function createTransport(mcpServerName, mcpServerConfig, debugMode, sendSdkMcpMessage) {
216549
+ if (isSdkMcpServerConfig(mcpServerConfig)) {
216550
+ if (!sendSdkMcpMessage) {
216551
+ throw new Error(
216552
+ `SDK MCP server '${mcpServerName}' requires sendSdkMcpMessage callback`
216553
+ );
216554
+ }
216555
+ return new SdkControlClientTransport({
216556
+ serverName: mcpServerName,
216557
+ sendMcpMessage: sendSdkMcpMessage,
216558
+ debugMode
216559
+ });
216560
+ }
216420
216561
  if (mcpServerConfig.authProviderType === "service_account_impersonation" /* SERVICE_ACCOUNT_IMPERSONATION */) {
216421
216562
  const provider = new ServiceAccountImpersonationProvider(mcpServerConfig);
216422
216563
  const transportOptions = {
@@ -216578,6 +216719,7 @@ var init_mcp_client = __esm({
216578
216719
  init_google_auth_provider();
216579
216720
  init_sa_impersonation_provider();
216580
216721
  init_mcp_tool();
216722
+ init_sdk_control_client_transport();
216581
216723
  init_node();
216582
216724
  init_oauth_provider();
216583
216725
  init_oauth_token_storage();
@@ -216597,13 +216739,14 @@ var init_mcp_client = __esm({
216597
216739
  return MCPDiscoveryState2;
216598
216740
  })(MCPDiscoveryState || {});
216599
216741
  McpClient = class {
216600
- constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode) {
216742
+ constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode, sendSdkMcpMessage) {
216601
216743
  this.serverName = serverName;
216602
216744
  this.serverConfig = serverConfig;
216603
216745
  this.toolRegistry = toolRegistry;
216604
216746
  this.promptRegistry = promptRegistry;
216605
216747
  this.workspaceContext = workspaceContext;
216606
216748
  this.debugMode = debugMode;
216749
+ this.sendSdkMcpMessage = sendSdkMcpMessage;
216607
216750
  this.client = new Client({
216608
216751
  name: `rdmind-cli-mcp-client-${this.serverName}`,
216609
216752
  version: "0.0.1"
@@ -216693,7 +216836,12 @@ var init_mcp_client = __esm({
216693
216836
  updateMCPServerStatus(this.serverName, status);
216694
216837
  }
216695
216838
  async createTransport() {
216696
- return createTransport(this.serverName, this.serverConfig, this.debugMode);
216839
+ return createTransport(
216840
+ this.serverName,
216841
+ this.serverConfig,
216842
+ this.debugMode,
216843
+ this.sendSdkMcpMessage
216844
+ );
216697
216845
  }
216698
216846
  async discoverTools(cliConfig) {
216699
216847
  return discoverTools(
@@ -216739,6 +216887,7 @@ var init_mcp_client_manager = __esm({
216739
216887
  "packages/core/src/tools/mcp-client-manager.ts"() {
216740
216888
  "use strict";
216741
216889
  init_esbuild_shims();
216890
+ init_config3();
216742
216891
  init_mcp_client();
216743
216892
  init_errors();
216744
216893
  McpClientManager = class {
@@ -216754,7 +216903,8 @@ var init_mcp_client_manager = __esm({
216754
216903
  workspaceContext;
216755
216904
  discoveryState = "not_started" /* NOT_STARTED */;
216756
216905
  eventEmitter;
216757
- constructor(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext, eventEmitter) {
216906
+ sendSdkMcpMessage;
216907
+ constructor(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext, eventEmitter, sendSdkMcpMessage) {
216758
216908
  this.mcpServers = mcpServers;
216759
216909
  this.mcpServerCommand = mcpServerCommand;
216760
216910
  this.toolRegistry = toolRegistry;
@@ -216762,6 +216912,7 @@ var init_mcp_client_manager = __esm({
216762
216912
  this.debugMode = debugMode;
216763
216913
  this.workspaceContext = workspaceContext;
216764
216914
  this.eventEmitter = eventEmitter;
216915
+ this.sendSdkMcpMessage = sendSdkMcpMessage;
216765
216916
  }
216766
216917
  /**
216767
216918
  * Initiates the tool discovery process for all configured MCP servers.
@@ -216781,13 +216932,15 @@ var init_mcp_client_manager = __esm({
216781
216932
  this.eventEmitter?.emit("mcp-client-update", this.clients);
216782
216933
  const discoveryPromises = Object.entries(servers).map(
216783
216934
  async ([name3, config2]) => {
216935
+ const sdkCallback = isSdkMcpServerConfig(config2) ? this.sendSdkMcpMessage : void 0;
216784
216936
  const client = new McpClient(
216785
216937
  name3,
216786
216938
  config2,
216787
216939
  this.toolRegistry,
216788
216940
  this.promptRegistry,
216789
216941
  this.workspaceContext,
216790
- this.debugMode
216942
+ this.debugMode,
216943
+ sdkCallback
216791
216944
  );
216792
216945
  this.clients.set(name3, client);
216793
216946
  this.eventEmitter?.emit("mcp-client-update", this.clients);
@@ -216974,7 +217127,7 @@ Signal: Signal number or \`(none)\` if no signal was received.
216974
217127
  tools = /* @__PURE__ */ new Map();
216975
217128
  config;
216976
217129
  mcpClientManager;
216977
- constructor(config2, eventEmitter) {
217130
+ constructor(config2, eventEmitter, sendSdkMcpMessage) {
216978
217131
  this.config = config2;
216979
217132
  this.mcpClientManager = new McpClientManager(
216980
217133
  this.config.getMcpServers() ?? {},
@@ -216983,7 +217136,8 @@ Signal: Signal number or \`(none)\` if no signal was received.
216983
217136
  this.config.getPromptRegistry(),
216984
217137
  this.config.getDebugMode(),
216985
217138
  this.config.getWorkspaceContext(),
216986
- eventEmitter
217139
+ eventEmitter,
217140
+ sendSdkMcpMessage
216987
217141
  );
216988
217142
  }
216989
217143
  /**
@@ -225625,6 +225779,9 @@ var init_workspaceContext = __esm({
225625
225779
  import * as path54 from "node:path";
225626
225780
  import process12 from "node:process";
225627
225781
  import { randomUUID as randomUUID6 } from "node:crypto";
225782
+ function isSdkMcpServerConfig(config2) {
225783
+ return config2.type === "sdk";
225784
+ }
225628
225785
  function normalizeConfigOutputFormat(format4) {
225629
225786
  if (!format4) {
225630
225787
  return void 0;
@@ -225723,7 +225880,7 @@ var init_config3 = __esm({
225723
225880
  DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD = 25e3;
225724
225881
  DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES = 1e3;
225725
225882
  MCPServerConfig = class {
225726
- constructor(command2, args, env7, cwd7, url3, httpUrl, headers, tcp, timeout2, trust, description, includeTools, excludeTools, extensionName, oauth, authProviderType, targetAudience, targetServiceAccount) {
225883
+ constructor(command2, args, env7, cwd7, url3, httpUrl, headers, tcp, timeout2, trust, description, includeTools, excludeTools, extensionName, oauth, authProviderType, targetAudience, targetServiceAccount, type) {
225727
225884
  this.command = command2;
225728
225885
  this.args = args;
225729
225886
  this.env = env7;
@@ -225742,11 +225899,13 @@ var init_config3 = __esm({
225742
225899
  this.authProviderType = authProviderType;
225743
225900
  this.targetAudience = targetAudience;
225744
225901
  this.targetServiceAccount = targetServiceAccount;
225902
+ this.type = type;
225745
225903
  }
225746
225904
  static {
225747
225905
  __name(this, "MCPServerConfig");
225748
225906
  }
225749
225907
  };
225908
+ __name(isSdkMcpServerConfig, "isSdkMcpServerConfig");
225750
225909
  AuthProviderType = /* @__PURE__ */ ((AuthProviderType2) => {
225751
225910
  AuthProviderType2["DYNAMIC_DISCOVERY"] = "dynamic_discovery";
225752
225911
  AuthProviderType2["GOOGLE_CREDENTIALS"] = "google_credentials";
@@ -225963,8 +226122,9 @@ var init_config3 = __esm({
225963
226122
  }
225964
226123
  /**
225965
226124
  * Must only be called once, throws if called again.
226125
+ * @param options Optional initialization options including sendSdkMcpMessage callback
225966
226126
  */
225967
- async initialize() {
226127
+ async initialize(options2) {
225968
226128
  if (this.initialized) {
225969
226129
  throw Error("Config was already initialized");
225970
226130
  }
@@ -225978,7 +226138,9 @@ var init_config3 = __esm({
225978
226138
  if (this.sessionSubagents.length > 0) {
225979
226139
  this.subagentManager.loadSessionSubagents(this.sessionSubagents);
225980
226140
  }
225981
- this.toolRegistry = await this.createToolRegistry();
226141
+ this.toolRegistry = await this.createToolRegistry(
226142
+ options2?.sendSdkMcpMessage
226143
+ );
225982
226144
  await this.geminiClient.initialize();
225983
226145
  logStartSession(this, new StartSessionEvent(this));
225984
226146
  }
@@ -226447,8 +226609,12 @@ var init_config3 = __esm({
226447
226609
  getSubagentManager() {
226448
226610
  return this.subagentManager;
226449
226611
  }
226450
- async createToolRegistry() {
226451
- const registry2 = new ToolRegistry(this, this.eventEmitter);
226612
+ async createToolRegistry(sendSdkMcpMessage) {
226613
+ const registry2 = new ToolRegistry(
226614
+ this,
226615
+ this.eventEmitter,
226616
+ sendSdkMcpMessage
226617
+ );
226452
226618
  const coreToolsConfig = this.getCoreTools();
226453
226619
  const excludeToolsConfig = this.getExcludeTools();
226454
226620
  const registerCoreTool = /* @__PURE__ */ __name((ToolClass, ...args) => {
@@ -226519,6 +226685,7 @@ var init_config3 = __esm({
226519
226685
  registerCoreTool(WebSearchTool, this);
226520
226686
  }
226521
226687
  await registry2.discoverAllTools();
226688
+ console.debug("ToolRegistry created", registry2.getAllToolNames());
226522
226689
  return registry2;
226523
226690
  }
226524
226691
  };
@@ -235631,7 +235798,9 @@ var init_src2 = __esm({
235631
235798
  init_read_many_files();
235632
235799
  init_read_knowledge_ext();
235633
235800
  init_mcp_client();
235801
+ init_mcp_client_manager();
235634
235802
  init_mcp_tool();
235803
+ init_sdk_control_client_transport();
235635
235804
  init_task();
235636
235805
  init_todoWrite();
235637
235806
  init_exitPlanMode();
@@ -235778,8 +235947,8 @@ var init_git_commit = __esm({
235778
235947
  "packages/core/src/generated/git-commit.ts"() {
235779
235948
  "use strict";
235780
235949
  init_esbuild_shims();
235781
- GIT_COMMIT_INFO = "72a170b5";
235782
- CLI_VERSION = "0.1.3-alpha.6";
235950
+ GIT_COMMIT_INFO = "4f0a7859";
235951
+ CLI_VERSION = "0.1.4-alpha.0";
235783
235952
  }
235784
235953
  });
235785
235954
 
@@ -236781,6 +236950,7 @@ __export(core_exports4, {
236781
236950
  MUTATOR_KINDS: () => MUTATOR_KINDS,
236782
236951
  MarkdownParser: () => MarkdownParser,
236783
236952
  McpClient: () => McpClient,
236953
+ McpClientManager: () => McpClientManager,
236784
236954
  MemoryMetricType: () => MemoryMetricType,
236785
236955
  MemoryTool: () => MemoryTool,
236786
236956
  MessageSenderType: () => MessageSenderType,
@@ -236817,6 +236987,7 @@ __export(core_exports4, {
236817
236987
  SUPPORTED_IMAGE_MIME_TYPES: () => SUPPORTED_IMAGE_MIME_TYPES,
236818
236988
  SYSTEM_FILE_EXCLUDES: () => SYSTEM_FILE_EXCLUDES,
236819
236989
  SchemaValidator: () => SchemaValidator,
236990
+ SdkControlClientTransport: () => SdkControlClientTransport,
236820
236991
  SemanticAttributes: () => SemanticAttributes,
236821
236992
  SessionService: () => SessionService,
236822
236993
  ShellExecutionService: () => ShellExecutionService,
@@ -236976,6 +237147,7 @@ __export(core_exports4, {
236976
237147
  isQwenQuotaExceededError: () => isQwenQuotaExceededError,
236977
237148
  isQwenThrottlingError: () => isQwenThrottlingError,
236978
237149
  isSchemaDepthError: () => isSchemaDepthError,
237150
+ isSdkMcpServerConfig: () => isSdkMcpServerConfig,
236979
237151
  isStructuredError: () => isStructuredError,
236980
237152
  isSubpath: () => isSubpath,
236981
237153
  isSupportedImageMimeType: () => isSupportedImageMimeType,
@@ -346248,7 +346420,7 @@ __name(getPackageJson, "getPackageJson");
346248
346420
  // packages/cli/src/utils/version.ts
346249
346421
  async function getCliVersion() {
346250
346422
  const pkgJson = await getPackageJson();
346251
- return "0.1.3-alpha.6";
346423
+ return "0.1.4-alpha.0";
346252
346424
  }
346253
346425
  __name(getCliVersion, "getCliVersion");
346254
346426
 
@@ -352615,7 +352787,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
352615
352787
 
352616
352788
  // packages/cli/src/generated/git-commit.ts
352617
352789
  init_esbuild_shims();
352618
- var GIT_COMMIT_INFO2 = "72a170b5";
352790
+ var GIT_COMMIT_INFO2 = "4f0a7859";
352619
352791
 
352620
352792
  // packages/cli/src/utils/systemInfo.ts
352621
352793
  async function getNpmVersion() {
@@ -355464,21 +355636,17 @@ This is a **NON-NEGOTIABLE** requirement. Even if the user writes in English, sa
355464
355636
 
355465
355637
  **Tool outputs**: All descriptive text from \`read_file\`, \`write_file\`, \`codebase_search\`, \`run_terminal_cmd\`, \`todo_write\`, \`web_search\`, etc. MUST be in ${language}.
355466
355638
 
355467
- **Thinking/Thoughts content**: If the model supports thinking mode or generates thoughts, ALL thinking and reasoning content MUST also be in ${language}. This applies to internal reasoning, thought processes, and any cognitive steps displayed to the user.
355468
-
355469
355639
  ## Examples
355470
355640
 
355471
355641
  ### \u2705 CORRECT:
355472
355642
  - User says "hi" \u2192 Respond in ${language} (e.g., "Bonjour" if ${language} is French)
355473
355643
  - Tool result \u2192 "\u5DF2\u6210\u529F\u8BFB\u53D6\u6587\u4EF6 config.json" (if ${language} is Chinese)
355474
355644
  - Error \u2192 "\u65E0\u6CD5\u627E\u5230\u6307\u5B9A\u7684\u6587\u4EF6" (if ${language} is Chinese)
355475
- - Thinking content \u2192 "\u6211\u6B63\u5728\u5206\u6790\u7528\u6237\u7684\u95EE\u9898..." (if ${language} is Chinese)
355476
355645
 
355477
355646
  ### \u274C WRONG:
355478
355647
  - User says "hi" \u2192 "Hello" in English
355479
355648
  - Tool result \u2192 "Successfully read file" in English
355480
355649
  - Error \u2192 "File not found" in English
355481
- - Thinking content \u2192 "I'm analyzing the user's question..." in English
355482
355650
 
355483
355651
  ## Notes
355484
355652
 
@@ -362133,11 +362301,30 @@ var BaseController = class {
362133
362301
  * Send an outgoing control request to SDK
362134
362302
  *
362135
362303
  * Manages lifecycle: register -> send -> wait for response -> deregister
362304
+ * Respects the provided AbortSignal for cancellation.
362136
362305
  */
362137
- async sendControlRequest(payload, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) {
362306
+ async sendControlRequest(payload, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS, signal) {
362307
+ if (signal?.aborted) {
362308
+ throw new Error("Request aborted");
362309
+ }
362138
362310
  const requestId = randomUUID9();
362139
362311
  return new Promise((resolve26, reject) => {
362312
+ const abortHandler = /* @__PURE__ */ __name(() => {
362313
+ this.registry.deregisterOutgoingRequest(requestId);
362314
+ reject(new Error("Request aborted"));
362315
+ if (this.context.debugMode) {
362316
+ console.error(
362317
+ `[${this.controllerName}] Outgoing request aborted: ${requestId}`
362318
+ );
362319
+ }
362320
+ }, "abortHandler");
362321
+ if (signal) {
362322
+ signal.addEventListener("abort", abortHandler, { once: true });
362323
+ }
362140
362324
  const timeoutId = setTimeout(() => {
362325
+ if (signal) {
362326
+ signal.removeEventListener("abort", abortHandler);
362327
+ }
362141
362328
  this.registry.deregisterOutgoingRequest(requestId);
362142
362329
  reject(new Error("Control request timeout"));
362143
362330
  if (this.context.debugMode) {
@@ -362146,11 +362333,23 @@ var BaseController = class {
362146
362333
  );
362147
362334
  }
362148
362335
  }, timeoutMs);
362336
+ const wrappedResolve = /* @__PURE__ */ __name((response) => {
362337
+ if (signal) {
362338
+ signal.removeEventListener("abort", abortHandler);
362339
+ }
362340
+ resolve26(response);
362341
+ }, "wrappedResolve");
362342
+ const wrappedReject = /* @__PURE__ */ __name((error2) => {
362343
+ if (signal) {
362344
+ signal.removeEventListener("abort", abortHandler);
362345
+ }
362346
+ reject(error2);
362347
+ }, "wrappedReject");
362149
362348
  this.registry.registerOutgoingRequest(
362150
362349
  requestId,
362151
362350
  this.controllerName,
362152
- resolve26,
362153
- reject,
362351
+ wrappedResolve,
362352
+ wrappedReject,
362154
362353
  timeoutId
362155
362354
  );
362156
362355
  const request4 = {
@@ -362161,6 +362360,9 @@ var BaseController = class {
362161
362360
  try {
362162
362361
  this.context.streamJson.send(request4);
362163
362362
  } catch (error2) {
362363
+ if (signal) {
362364
+ signal.removeEventListener("abort", abortHandler);
362365
+ }
362164
362366
  this.registry.deregisterOutgoingRequest(requestId);
362165
362367
  reject(error2);
362166
362368
  }
@@ -362174,6 +362376,7 @@ var BaseController = class {
362174
362376
  };
362175
362377
 
362176
362378
  // packages/cli/src/nonInteractive/control/controllers/systemController.ts
362379
+ init_core4();
362177
362380
  var SystemController = class extends BaseController {
362178
362381
  static {
362179
362382
  __name(this, "SystemController");
@@ -362181,16 +362384,25 @@ var SystemController = class extends BaseController {
362181
362384
  /**
362182
362385
  * Handle system control requests
362183
362386
  */
362184
- async handleRequestPayload(payload, _signal) {
362387
+ async handleRequestPayload(payload, signal) {
362388
+ if (signal.aborted) {
362389
+ throw new Error("Request aborted");
362390
+ }
362185
362391
  switch (payload.subtype) {
362186
362392
  case "initialize":
362187
- return this.handleInitialize(payload);
362393
+ return this.handleInitialize(
362394
+ payload,
362395
+ signal
362396
+ );
362188
362397
  case "interrupt":
362189
362398
  return this.handleInterrupt();
362190
362399
  case "set_model":
362191
- return this.handleSetModel(payload);
362400
+ return this.handleSetModel(
362401
+ payload,
362402
+ signal
362403
+ );
362192
362404
  case "supported_commands":
362193
- return this.handleSupportedCommands();
362405
+ return this.handleSupportedCommands(signal);
362194
362406
  default:
362195
362407
  throw new Error(`Unsupported request subtype in SystemController`);
362196
362408
  }
@@ -362198,41 +362410,108 @@ var SystemController = class extends BaseController {
362198
362410
  /**
362199
362411
  * Handle initialize request
362200
362412
  *
362201
- * Registers SDK MCP servers and returns capabilities
362413
+ * Processes SDK MCP servers config.
362414
+ * SDK servers are registered in context.sdkMcpServers
362415
+ * and added to config.mcpServers with the sdk type flag.
362416
+ * External MCP servers are configured separately in settings.
362202
362417
  */
362203
- async handleInitialize(payload) {
362418
+ async handleInitialize(payload, signal) {
362419
+ if (signal.aborted) {
362420
+ throw new Error("Request aborted");
362421
+ }
362204
362422
  this.context.config.setSdkMode(true);
362205
- if (payload.sdkMcpServers && typeof payload.sdkMcpServers === "object") {
362206
- for (const serverName of Object.keys(payload.sdkMcpServers)) {
362207
- this.context.sdkMcpServers.add(serverName);
362423
+ if (payload.sdkMcpServers && typeof payload.sdkMcpServers === "object" && payload.sdkMcpServers !== null) {
362424
+ const sdkServers = {};
362425
+ for (const [key, wireConfig] of Object.entries(payload.sdkMcpServers)) {
362426
+ const name3 = typeof wireConfig?.name === "string" && wireConfig.name.trim().length ? wireConfig.name : key;
362427
+ this.context.sdkMcpServers.add(name3);
362428
+ sdkServers[name3] = new MCPServerConfig(
362429
+ void 0,
362430
+ // command
362431
+ void 0,
362432
+ // args
362433
+ void 0,
362434
+ // env
362435
+ void 0,
362436
+ // cwd
362437
+ void 0,
362438
+ // url
362439
+ void 0,
362440
+ // httpUrl
362441
+ void 0,
362442
+ // headers
362443
+ void 0,
362444
+ // tcp
362445
+ void 0,
362446
+ // timeout
362447
+ true,
362448
+ // trust - SDK servers are trusted
362449
+ void 0,
362450
+ // description
362451
+ void 0,
362452
+ // includeTools
362453
+ void 0,
362454
+ // excludeTools
362455
+ void 0,
362456
+ // extensionName
362457
+ void 0,
362458
+ // oauth
362459
+ void 0,
362460
+ // authProviderType
362461
+ void 0,
362462
+ // targetAudience
362463
+ void 0,
362464
+ // targetServiceAccount
362465
+ "sdk"
362466
+ // type
362467
+ );
362208
362468
  }
362209
- try {
362210
- this.context.config.addMcpServers(payload.sdkMcpServers);
362211
- if (this.context.debugMode) {
362212
- console.error(
362213
- `[SystemController] Added ${Object.keys(payload.sdkMcpServers).length} SDK MCP servers to config`
362214
- );
362215
- }
362216
- } catch (error2) {
362217
- if (this.context.debugMode) {
362218
- console.error(
362219
- "[SystemController] Failed to add SDK MCP servers:",
362220
- error2
362221
- );
362469
+ const sdkServerCount = Object.keys(sdkServers).length;
362470
+ if (sdkServerCount > 0) {
362471
+ try {
362472
+ this.context.config.addMcpServers(sdkServers);
362473
+ if (this.context.debugMode) {
362474
+ console.error(
362475
+ `[SystemController] Added ${sdkServerCount} SDK MCP servers to config`
362476
+ );
362477
+ }
362478
+ } catch (error2) {
362479
+ if (this.context.debugMode) {
362480
+ console.error(
362481
+ "[SystemController] Failed to add SDK MCP servers:",
362482
+ error2
362483
+ );
362484
+ }
362222
362485
  }
362223
362486
  }
362224
362487
  }
362225
- if (payload.mcpServers && typeof payload.mcpServers === "object") {
362226
- try {
362227
- this.context.config.addMcpServers(payload.mcpServers);
362228
- if (this.context.debugMode) {
362229
- console.error(
362230
- `[SystemController] Added ${Object.keys(payload.mcpServers).length} MCP servers to config`
362231
- );
362488
+ if (payload.mcpServers && typeof payload.mcpServers === "object" && payload.mcpServers !== null) {
362489
+ const externalServers = {};
362490
+ for (const [name3, serverConfig] of Object.entries(payload.mcpServers)) {
362491
+ const normalized2 = this.normalizeMcpServerConfig(
362492
+ name3,
362493
+ serverConfig
362494
+ );
362495
+ if (normalized2) {
362496
+ externalServers[name3] = normalized2;
362232
362497
  }
362233
- } catch (error2) {
362234
- if (this.context.debugMode) {
362235
- console.error("[SystemController] Failed to add MCP servers:", error2);
362498
+ }
362499
+ const externalCount = Object.keys(externalServers).length;
362500
+ if (externalCount > 0) {
362501
+ try {
362502
+ this.context.config.addMcpServers(externalServers);
362503
+ if (this.context.debugMode) {
362504
+ console.error(
362505
+ `[SystemController] Added ${externalCount} external MCP servers to config`
362506
+ );
362507
+ }
362508
+ } catch (error2) {
362509
+ if (this.context.debugMode) {
362510
+ console.error(
362511
+ "[SystemController] Failed to add external MCP servers:",
362512
+ error2
362513
+ );
362514
+ }
362236
362515
  }
362237
362516
  }
362238
362517
  }
@@ -362277,11 +362556,80 @@ var SystemController = class extends BaseController {
362277
362556
  can_handle_hook_callback: false,
362278
362557
  can_set_permission_mode: typeof this.context.config.setApprovalMode === "function",
362279
362558
  can_set_model: typeof this.context.config.setModel === "function",
362280
- /* TODO: sdkMcpServers support */
362281
- can_handle_mcp_message: false
362559
+ // SDK MCP servers are supported - messages routed through control plane
362560
+ can_handle_mcp_message: true
362282
362561
  };
362283
362562
  return capabilities;
362284
362563
  }
362564
+ normalizeMcpServerConfig(serverName, config2) {
362565
+ if (!config2 || typeof config2 !== "object") {
362566
+ if (this.context.debugMode) {
362567
+ console.error(
362568
+ `[SystemController] Ignoring invalid MCP server config for '${serverName}'`
362569
+ );
362570
+ }
362571
+ return null;
362572
+ }
362573
+ const authProvider = this.normalizeAuthProviderType(
362574
+ config2.authProviderType
362575
+ );
362576
+ const oauthConfig = this.normalizeOAuthConfig(config2.oauth);
362577
+ return new MCPServerConfig(
362578
+ config2.command,
362579
+ config2.args,
362580
+ config2.env,
362581
+ config2.cwd,
362582
+ config2.url,
362583
+ config2.httpUrl,
362584
+ config2.headers,
362585
+ config2.tcp,
362586
+ config2.timeout,
362587
+ config2.trust,
362588
+ config2.description,
362589
+ config2.includeTools,
362590
+ config2.excludeTools,
362591
+ config2.extensionName,
362592
+ oauthConfig,
362593
+ authProvider,
362594
+ config2.targetAudience,
362595
+ config2.targetServiceAccount
362596
+ );
362597
+ }
362598
+ normalizeAuthProviderType(value) {
362599
+ if (!value) {
362600
+ return void 0;
362601
+ }
362602
+ switch (value) {
362603
+ case "dynamic_discovery" /* DYNAMIC_DISCOVERY */:
362604
+ case "google_credentials" /* GOOGLE_CREDENTIALS */:
362605
+ case "service_account_impersonation" /* SERVICE_ACCOUNT_IMPERSONATION */:
362606
+ return value;
362607
+ default:
362608
+ if (this.context.debugMode) {
362609
+ console.error(
362610
+ `[SystemController] Unsupported authProviderType '${value}', skipping`
362611
+ );
362612
+ }
362613
+ return void 0;
362614
+ }
362615
+ }
362616
+ normalizeOAuthConfig(oauth) {
362617
+ if (!oauth) {
362618
+ return void 0;
362619
+ }
362620
+ return {
362621
+ enabled: oauth.enabled,
362622
+ clientId: oauth.clientId,
362623
+ clientSecret: oauth.clientSecret,
362624
+ authorizationUrl: oauth.authorizationUrl,
362625
+ tokenUrl: oauth.tokenUrl,
362626
+ scopes: oauth.scopes,
362627
+ audiences: oauth.audiences,
362628
+ redirectUri: oauth.redirectUri,
362629
+ tokenParamName: oauth.tokenParamName,
362630
+ registrationUrl: oauth.registrationUrl
362631
+ };
362632
+ }
362285
362633
  /**
362286
362634
  * Handle interrupt request
362287
362635
  *
@@ -362306,7 +362654,10 @@ var SystemController = class extends BaseController {
362306
362654
  *
362307
362655
  * Implements actual model switching with validation and error handling
362308
362656
  */
362309
- async handleSetModel(payload) {
362657
+ async handleSetModel(payload, signal) {
362658
+ if (signal.aborted) {
362659
+ throw new Error("Request aborted");
362660
+ }
362310
362661
  const model = payload.model;
362311
362662
  if (typeof model !== "string" || model.trim() === "") {
362312
362663
  throw new Error("Invalid model specified for set_model request");
@@ -362336,8 +362687,11 @@ var SystemController = class extends BaseController {
362336
362687
  *
362337
362688
  * Returns list of supported slash commands loaded dynamically
362338
362689
  */
362339
- async handleSupportedCommands() {
362340
- const slashCommands = await this.loadSlashCommandNames();
362690
+ async handleSupportedCommands(signal) {
362691
+ if (signal.aborted) {
362692
+ throw new Error("Request aborted");
362693
+ }
362694
+ const slashCommands = await this.loadSlashCommandNames(signal);
362341
362695
  return {
362342
362696
  subtype: "supported_commands",
362343
362697
  commands: slashCommands
@@ -362346,15 +362700,21 @@ var SystemController = class extends BaseController {
362346
362700
  /**
362347
362701
  * Load slash command names using CommandService
362348
362702
  *
362703
+ * @param signal - AbortSignal to respect for cancellation
362349
362704
  * @returns Promise resolving to array of slash command names
362350
362705
  */
362351
- async loadSlashCommandNames() {
362352
- const controller = new AbortController();
362706
+ async loadSlashCommandNames(signal) {
362707
+ if (signal.aborted) {
362708
+ return [];
362709
+ }
362353
362710
  try {
362354
362711
  const service = await CommandService.create(
362355
362712
  [new BuiltinCommandLoader(this.context.config)],
362356
- controller.signal
362713
+ signal
362357
362714
  );
362715
+ if (signal.aborted) {
362716
+ return [];
362717
+ }
362358
362718
  const names = /* @__PURE__ */ new Set();
362359
362719
  const commands = service.getCommands();
362360
362720
  for (const command2 of commands) {
@@ -362362,6 +362722,9 @@ var SystemController = class extends BaseController {
362362
362722
  }
362363
362723
  return Array.from(names).sort();
362364
362724
  } catch (error2) {
362725
+ if (signal.aborted) {
362726
+ return [];
362727
+ }
362365
362728
  if (this.context.debugMode) {
362366
362729
  console.error(
362367
362730
  "[SystemController] Failed to load slash commands:",
@@ -362369,8 +362732,6 @@ var SystemController = class extends BaseController {
362369
362732
  );
362370
362733
  }
362371
362734
  return [];
362372
- } finally {
362373
- controller.abort();
362374
362735
  }
362375
362736
  }
362376
362737
  };
@@ -362386,13 +362747,20 @@ var PermissionController = class extends BaseController {
362386
362747
  /**
362387
362748
  * Handle permission control requests
362388
362749
  */
362389
- async handleRequestPayload(payload, _signal) {
362750
+ async handleRequestPayload(payload, signal) {
362751
+ if (signal.aborted) {
362752
+ throw new Error("Request aborted");
362753
+ }
362390
362754
  switch (payload.subtype) {
362391
362755
  case "can_use_tool":
362392
- return this.handleCanUseTool(payload);
362756
+ return this.handleCanUseTool(
362757
+ payload,
362758
+ signal
362759
+ );
362393
362760
  case "set_permission_mode":
362394
362761
  return this.handleSetPermissionMode(
362395
- payload
362762
+ payload,
362763
+ signal
362396
362764
  );
362397
362765
  default:
362398
362766
  throw new Error(`Unsupported request subtype in PermissionController`);
@@ -362406,7 +362774,10 @@ var PermissionController = class extends BaseController {
362406
362774
  * - Tool registry validation
362407
362775
  * - Error handling with safe defaults
362408
362776
  */
362409
- async handleCanUseTool(payload) {
362777
+ async handleCanUseTool(payload, signal) {
362778
+ if (signal.aborted) {
362779
+ throw new Error("Request aborted");
362780
+ }
362410
362781
  const toolName = payload.tool_name;
362411
362782
  if (!toolName || typeof toolName !== "string" || toolName.trim().length === 0) {
362412
362783
  return {
@@ -362493,7 +362864,10 @@ var PermissionController = class extends BaseController {
362493
362864
  *
362494
362865
  * Updates the permission mode in the context
362495
362866
  */
362496
- async handleSetPermissionMode(payload) {
362867
+ async handleSetPermissionMode(payload, signal) {
362868
+ if (signal.aborted) {
362869
+ throw new Error("Request aborted");
362870
+ }
362497
362871
  const mode = payload.mode;
362498
362872
  const validModes = [
362499
362873
  "default",
@@ -362641,6 +363015,12 @@ var PermissionController = class extends BaseController {
362641
363015
  */
362642
363016
  async handleOutgoingPermissionRequest(toolCall) {
362643
363017
  try {
363018
+ if (this.context.abortSignal?.aborted) {
363019
+ await toolCall.confirmationDetails.onConfirm(
363020
+ "cancel" /* Cancel */
363021
+ );
363022
+ return;
363023
+ }
362644
363024
  const inputFormat = this.context.config.getInputFormat?.();
362645
363025
  const isStreamJsonMode = inputFormat === "stream-json" /* STREAM_JSON */;
362646
363026
  if (!isStreamJsonMode) {
@@ -362652,14 +363032,19 @@ var PermissionController = class extends BaseController {
362652
363032
  const permissionSuggestions = this.buildPermissionSuggestions(
362653
363033
  toolCall.confirmationDetails
362654
363034
  );
362655
- const response = await this.sendControlRequest({
362656
- subtype: "can_use_tool",
362657
- tool_name: toolCall.request.name,
362658
- tool_use_id: toolCall.request.callId,
362659
- input: toolCall.request.args,
362660
- permission_suggestions: permissionSuggestions,
362661
- blocked_path: null
362662
- });
363035
+ const response = await this.sendControlRequest(
363036
+ {
363037
+ subtype: "can_use_tool",
363038
+ tool_name: toolCall.request.name,
363039
+ tool_use_id: toolCall.request.callId,
363040
+ input: toolCall.request.args,
363041
+ permission_suggestions: permissionSuggestions,
363042
+ blocked_path: null
363043
+ },
363044
+ void 0,
363045
+ // use default timeout
363046
+ this.context.abortSignal
363047
+ );
362663
363048
  if (response.subtype !== "success") {
362664
363049
  await toolCall.confirmationDetails.onConfirm(
362665
363050
  "cancel" /* Cancel */
@@ -362708,6 +363093,98 @@ var PermissionController = class extends BaseController {
362708
363093
  }
362709
363094
  };
362710
363095
 
363096
+ // packages/cli/src/nonInteractive/control/controllers/sdkMcpController.ts
363097
+ init_esbuild_shims();
363098
+ var MCP_REQUEST_TIMEOUT = 3e4;
363099
+ var SdkMcpController = class extends BaseController {
363100
+ static {
363101
+ __name(this, "SdkMcpController");
363102
+ }
363103
+ /**
363104
+ * Handle SDK MCP control requests from ControlDispatcher
363105
+ *
363106
+ * Note: mcp_message requests are NOT handled here. CLI MCP clients
363107
+ * send messages via the sendSdkMcpMessage callback directly, not
363108
+ * through the control dispatcher.
363109
+ */
363110
+ async handleRequestPayload(payload, signal) {
363111
+ if (signal.aborted) {
363112
+ throw new Error("Request aborted");
363113
+ }
363114
+ switch (payload.subtype) {
363115
+ case "mcp_server_status":
363116
+ return this.handleMcpStatus();
363117
+ default:
363118
+ throw new Error(`Unsupported request subtype in SdkMcpController`);
363119
+ }
363120
+ }
363121
+ /**
363122
+ * Handle mcp_server_status request
363123
+ *
363124
+ * Returns status of all registered SDK MCP servers.
363125
+ * SDK servers are considered "connected" if they are registered.
363126
+ */
363127
+ async handleMcpStatus() {
363128
+ const status = {};
363129
+ for (const serverName of this.context.sdkMcpServers) {
363130
+ status[serverName] = "connected";
363131
+ }
363132
+ return {
363133
+ subtype: "mcp_server_status",
363134
+ status
363135
+ };
363136
+ }
363137
+ /**
363138
+ * Send MCP message to SDK server via control plane
363139
+ *
363140
+ * @param serverName - Name of the SDK MCP server
363141
+ * @param message - MCP JSON-RPC message to send
363142
+ * @returns MCP JSON-RPC response from SDK server
363143
+ */
363144
+ async sendMcpMessageToSdk(serverName, message) {
363145
+ if (this.context.debugMode) {
363146
+ console.error(
363147
+ `[SdkMcpController] Sending MCP message to SDK server '${serverName}':`,
363148
+ JSON.stringify(message)
363149
+ );
363150
+ }
363151
+ const response = await this.sendControlRequest(
363152
+ {
363153
+ subtype: "mcp_message",
363154
+ server_name: serverName,
363155
+ message
363156
+ },
363157
+ MCP_REQUEST_TIMEOUT,
363158
+ this.context.abortSignal
363159
+ );
363160
+ const responsePayload = response.response;
363161
+ const mcpResponse = responsePayload?.["mcp_response"];
363162
+ if (!mcpResponse) {
363163
+ throw new Error(
363164
+ `Invalid MCP response from SDK for server '${serverName}'`
363165
+ );
363166
+ }
363167
+ if (this.context.debugMode) {
363168
+ console.error(
363169
+ `[SdkMcpController] Received MCP response from SDK server '${serverName}':`,
363170
+ JSON.stringify(mcpResponse)
363171
+ );
363172
+ }
363173
+ return mcpResponse;
363174
+ }
363175
+ /**
363176
+ * Create a callback function for sending MCP messages to SDK servers.
363177
+ *
363178
+ * This callback is used by McpClientManager/SdkControlClientTransport to send
363179
+ * MCP messages from CLI MCP clients to SDK MCP servers via the control plane.
363180
+ *
363181
+ * @returns A function that sends MCP messages to SDK and returns the response
363182
+ */
363183
+ createSendSdkMcpMessage() {
363184
+ return (serverName, message) => this.sendMcpMessageToSdk(serverName, message);
363185
+ }
363186
+ };
363187
+
362711
363188
  // packages/cli/src/nonInteractive/control/ControlDispatcher.ts
362712
363189
  var ControlDispatcher = class {
362713
363190
  static {
@@ -362717,7 +363194,7 @@ var ControlDispatcher = class {
362717
363194
  // Make controllers publicly accessible
362718
363195
  systemController;
362719
363196
  permissionController;
362720
- // readonly mcpController: MCPController;
363197
+ sdkMcpController;
362721
363198
  // readonly hookController: HookController;
362722
363199
  // Central pending request registries
362723
363200
  pendingIncomingRequests = /* @__PURE__ */ new Map();
@@ -362734,6 +363211,11 @@ var ControlDispatcher = class {
362734
363211
  this,
362735
363212
  "PermissionController"
362736
363213
  );
363214
+ this.sdkMcpController = new SdkMcpController(
363215
+ context2,
363216
+ this,
363217
+ "SdkMcpController"
363218
+ );
362737
363219
  this.context.abortSignal.addEventListener("abort", () => {
362738
363220
  this.shutdown();
362739
363221
  });
@@ -362839,6 +363321,7 @@ var ControlDispatcher = class {
362839
363321
  this.pendingOutgoingRequests.clear();
362840
363322
  this.systemController.cleanup();
362841
363323
  this.permissionController.cleanup();
363324
+ this.sdkMcpController.cleanup();
362842
363325
  }
362843
363326
  /**
362844
363327
  * Registers an incoming request in the pending registry
@@ -362881,6 +363364,40 @@ var ControlDispatcher = class {
362881
363364
  this.pendingOutgoingRequests.delete(requestId);
362882
363365
  }
362883
363366
  }
363367
+ /**
363368
+ * Get count of pending incoming requests (for debugging)
363369
+ */
363370
+ getPendingIncomingRequestCount() {
363371
+ return this.pendingIncomingRequests.size;
363372
+ }
363373
+ /**
363374
+ * Wait for all incoming request handlers to complete.
363375
+ *
363376
+ * Uses polling since we don't have direct Promise references to handlers.
363377
+ * The pendingIncomingRequests map is managed by BaseController:
363378
+ * - Registered when handler starts (in handleRequest)
363379
+ * - Deregistered when handler completes (success or error)
363380
+ *
363381
+ * @param pollIntervalMs - How often to check (default 50ms)
363382
+ * @param timeoutMs - Maximum wait time (default 30s)
363383
+ */
363384
+ async waitForPendingIncomingRequests(pollIntervalMs = 50, timeoutMs = 3e4) {
363385
+ const startTime = Date.now();
363386
+ while (this.pendingIncomingRequests.size > 0) {
363387
+ if (Date.now() - startTime > timeoutMs) {
363388
+ if (this.context.debugMode) {
363389
+ console.error(
363390
+ `[ControlDispatcher] Timeout waiting for ${this.pendingIncomingRequests.size} pending incoming requests`
363391
+ );
363392
+ }
363393
+ break;
363394
+ }
363395
+ await new Promise((resolve26) => setTimeout(resolve26, pollIntervalMs));
363396
+ }
363397
+ if (this.context.debugMode && this.pendingIncomingRequests.size === 0) {
363398
+ console.error("[ControlDispatcher] All incoming requests completed");
363399
+ }
363400
+ }
362884
363401
  /**
362885
363402
  * Returns the controller that handles the given request subtype
362886
363403
  */
@@ -362894,9 +363411,8 @@ var ControlDispatcher = class {
362894
363411
  case "can_use_tool":
362895
363412
  case "set_permission_mode":
362896
363413
  return this.permissionController;
362897
- // case 'mcp_message':
362898
- // case 'mcp_server_status':
362899
- // return this.mcpController;
363414
+ case "mcp_server_status":
363415
+ return this.sdkMcpController;
362900
363416
  // case 'hook_callback':
362901
363417
  // return this.hookController;
362902
363418
  default:
@@ -363175,6 +363691,11 @@ var Session2 = class {
363175
363691
  processingPromise = null;
363176
363692
  isShuttingDown = false;
363177
363693
  configInitialized = false;
363694
+ // Single initialization promise that resolves when session is ready for user messages.
363695
+ // Created lazily once initialization actually starts.
363696
+ initializationPromise = null;
363697
+ initializationResolve = null;
363698
+ initializationReject = null;
363178
363699
  constructor(config2, initialPrompt) {
363179
363700
  this.config = config2;
363180
363701
  this.sessionId = config2.getSessionId();
@@ -363188,11 +363709,28 @@ var Session2 = class {
363188
363709
  );
363189
363710
  this.setupSignalHandlers();
363190
363711
  }
363712
+ ensureInitializationPromise() {
363713
+ if (this.initializationPromise) {
363714
+ return;
363715
+ }
363716
+ this.initializationPromise = new Promise((resolve26, reject) => {
363717
+ this.initializationResolve = () => {
363718
+ resolve26();
363719
+ this.initializationResolve = null;
363720
+ this.initializationReject = null;
363721
+ };
363722
+ this.initializationReject = (error2) => {
363723
+ reject(error2);
363724
+ this.initializationResolve = null;
363725
+ this.initializationReject = null;
363726
+ };
363727
+ });
363728
+ }
363191
363729
  getNextPromptId() {
363192
363730
  this.promptIdCounter++;
363193
363731
  return `${this.sessionId}########${this.promptIdCounter}`;
363194
363732
  }
363195
- async ensureConfigInitialized() {
363733
+ async ensureConfigInitialized(options2) {
363196
363734
  if (this.configInitialized) {
363197
363735
  return;
363198
363736
  }
@@ -363200,7 +363738,7 @@ var Session2 = class {
363200
363738
  console.error("[Session] Initializing config");
363201
363739
  }
363202
363740
  try {
363203
- await this.config.initialize();
363741
+ await this.config.initialize(options2);
363204
363742
  this.configInitialized = true;
363205
363743
  } catch (error2) {
363206
363744
  if (this.debugMode) {
@@ -363209,6 +363747,41 @@ var Session2 = class {
363209
363747
  throw error2;
363210
363748
  }
363211
363749
  }
363750
+ /**
363751
+ * Mark initialization as complete
363752
+ */
363753
+ completeInitialization() {
363754
+ if (this.initializationResolve) {
363755
+ if (this.debugMode) {
363756
+ console.error("[Session] Initialization complete");
363757
+ }
363758
+ this.initializationResolve();
363759
+ this.initializationResolve = null;
363760
+ this.initializationReject = null;
363761
+ }
363762
+ }
363763
+ /**
363764
+ * Mark initialization as failed
363765
+ */
363766
+ failInitialization(error2) {
363767
+ if (this.initializationReject) {
363768
+ if (this.debugMode) {
363769
+ console.error("[Session] Initialization failed:", error2);
363770
+ }
363771
+ this.initializationReject(error2);
363772
+ this.initializationResolve = null;
363773
+ this.initializationReject = null;
363774
+ }
363775
+ }
363776
+ /**
363777
+ * Wait for session to be ready for user messages
363778
+ */
363779
+ async waitForInitialization() {
363780
+ if (!this.initializationPromise) {
363781
+ return;
363782
+ }
363783
+ await this.initializationPromise;
363784
+ }
363212
363785
  ensureControlSystem() {
363213
363786
  if (this.controlContext && this.dispatcher && this.controlService) {
363214
363787
  return;
@@ -363236,33 +363809,81 @@ var Session2 = class {
363236
363809
  }
363237
363810
  return this.dispatcher;
363238
363811
  }
363239
- async handleFirstMessage(message) {
363812
+ /**
363813
+ * Handle the first message to determine session mode (SDK vs direct).
363814
+ * This is synchronous from the message loop's perspective - it starts
363815
+ * async work but does not return a promise that the loop awaits.
363816
+ *
363817
+ * The initialization completes asynchronously and resolves initializationPromise
363818
+ * when ready for user messages.
363819
+ */
363820
+ handleFirstMessage(message) {
363240
363821
  if (isControlRequest(message)) {
363241
363822
  const request4 = message;
363242
363823
  this.controlSystemEnabled = true;
363243
363824
  this.ensureControlSystem();
363244
363825
  if (request4.request.subtype === "initialize") {
363245
- await this.dispatcher?.dispatch(request4);
363246
- await this.ensureConfigInitialized();
363247
- return true;
363826
+ void this.initializeSdkMode(request4);
363827
+ return;
363248
363828
  }
363249
363829
  if (this.debugMode) {
363250
363830
  console.error(
363251
363831
  "[Session] Ignoring non-initialize control request during initialization"
363252
363832
  );
363253
363833
  }
363254
- return true;
363834
+ return;
363255
363835
  }
363256
363836
  if (isCLIUserMessage(message)) {
363257
363837
  this.controlSystemEnabled = false;
363258
- await this.ensureConfigInitialized();
363259
- this.enqueueUserMessage(message);
363260
- return true;
363838
+ void this.initializeDirectMode(message);
363839
+ return;
363261
363840
  }
363262
363841
  this.controlSystemEnabled = false;
363263
- return false;
363264
363842
  }
363265
- async handleControlRequest(request4) {
363843
+ /**
363844
+ * SDK mode initialization flow
363845
+ * Dispatches initialize request and initializes config with MCP support
363846
+ */
363847
+ async initializeSdkMode(request4) {
363848
+ this.ensureInitializationPromise();
363849
+ try {
363850
+ await this.dispatcher?.dispatch(request4);
363851
+ const sendSdkMcpMessage = this.dispatcher?.sdkMcpController.createSendSdkMcpMessage();
363852
+ await this.ensureConfigInitialized({ sendSdkMcpMessage });
363853
+ this.completeInitialization();
363854
+ } catch (error2) {
363855
+ if (this.debugMode) {
363856
+ console.error("[Session] SDK mode initialization failed:", error2);
363857
+ }
363858
+ this.failInitialization(
363859
+ error2 instanceof Error ? error2 : new Error(String(error2))
363860
+ );
363861
+ }
363862
+ }
363863
+ /**
363864
+ * Direct mode initialization flow
363865
+ * Initializes config and enqueues the first user message
363866
+ */
363867
+ async initializeDirectMode(userMessage) {
363868
+ this.ensureInitializationPromise();
363869
+ try {
363870
+ await this.ensureConfigInitialized();
363871
+ this.completeInitialization();
363872
+ this.enqueueUserMessage(userMessage);
363873
+ } catch (error2) {
363874
+ if (this.debugMode) {
363875
+ console.error("[Session] Direct mode initialization failed:", error2);
363876
+ }
363877
+ this.failInitialization(
363878
+ error2 instanceof Error ? error2 : new Error(String(error2))
363879
+ );
363880
+ }
363881
+ }
363882
+ /**
363883
+ * Handle control request asynchronously (fire-and-forget from main loop).
363884
+ * Errors are handled internally and responses sent by dispatcher.
363885
+ */
363886
+ handleControlRequestAsync(request4) {
363266
363887
  const dispatcher = this.getDispatcher();
363267
363888
  if (!dispatcher) {
363268
363889
  if (this.debugMode) {
@@ -363270,8 +363891,16 @@ var Session2 = class {
363270
363891
  }
363271
363892
  return;
363272
363893
  }
363273
- await dispatcher.dispatch(request4);
363894
+ void dispatcher.dispatch(request4).catch((error2) => {
363895
+ if (this.debugMode) {
363896
+ console.error("[Session] Control request dispatch error:", error2);
363897
+ }
363898
+ });
363274
363899
  }
363900
+ /**
363901
+ * Handle control response - MUST be synchronous
363902
+ * This resolves pending outgoing requests, breaking the deadlock cycle.
363903
+ */
363275
363904
  handleControlResponse(response) {
363276
363905
  const dispatcher = this.getDispatcher();
363277
363906
  if (!dispatcher) {
@@ -363294,7 +363923,7 @@ var Session2 = class {
363294
363923
  }
363295
363924
  return;
363296
363925
  }
363297
- await this.ensureConfigInitialized();
363926
+ await this.waitForInitialization();
363298
363927
  const promptId = this.getNextPromptId();
363299
363928
  try {
363300
363929
  await runNonInteractive(
@@ -363374,23 +364003,45 @@ var Session2 = class {
363374
364003
  process.on("SIGINT", this.shutdownHandler);
363375
364004
  process.on("SIGTERM", this.shutdownHandler);
363376
364005
  }
363377
- async shutdown() {
363378
- if (this.debugMode) {
363379
- console.error("[Session] Shutting down");
364006
+ /**
364007
+ * Wait for all pending work to complete before shutdown
364008
+ */
364009
+ async waitForAllPendingWork() {
364010
+ try {
364011
+ await this.waitForInitialization();
364012
+ } catch (error2) {
364013
+ if (this.debugMode) {
364014
+ console.error("[Session] Initialization error during shutdown:", error2);
364015
+ }
363380
364016
  }
363381
- this.isShuttingDown = true;
363382
- if (this.processingPromise) {
364017
+ if (this.dispatcher) {
364018
+ const pendingCount = this.dispatcher.getPendingIncomingRequestCount();
364019
+ if (pendingCount > 0 && this.debugMode) {
364020
+ console.error(
364021
+ `[Session] Waiting for ${pendingCount} pending control request handlers`
364022
+ );
364023
+ }
364024
+ await this.dispatcher.waitForPendingIncomingRequests();
364025
+ }
364026
+ while (this.processingPromise) {
364027
+ if (this.debugMode) {
364028
+ console.error("[Session] Waiting for user message processing");
364029
+ }
363383
364030
  try {
363384
364031
  await this.processingPromise;
363385
364032
  } catch (error2) {
363386
364033
  if (this.debugMode) {
363387
- console.error(
363388
- "[Session] Error waiting for processing to complete:",
363389
- error2
363390
- );
364034
+ console.error("[Session] Error in user message processing:", error2);
363391
364035
  }
363392
364036
  }
363393
364037
  }
364038
+ }
364039
+ async shutdown() {
364040
+ if (this.debugMode) {
364041
+ console.error("[Session] Shutting down");
364042
+ }
364043
+ this.isShuttingDown = true;
364044
+ await this.waitForAllPendingWork();
363394
364045
  this.dispatcher?.shutdown();
363395
364046
  this.cleanupSignalHandlers();
363396
364047
  }
@@ -363401,36 +364052,44 @@ var Session2 = class {
363401
364052
  this.shutdownHandler = null;
363402
364053
  }
363403
364054
  }
364055
+ /**
364056
+ * Main message processing loop
364057
+ *
364058
+ * CRITICAL: This loop must NEVER await handlers that might need to
364059
+ * send control requests and wait for responses. Such handlers must
364060
+ * be started in fire-and-forget mode, allowing the loop to continue
364061
+ * reading responses that resolve pending requests.
364062
+ *
364063
+ * Message handling order:
364064
+ * 1. control_response - FIRST, synchronously resolves pending requests
364065
+ * 2. First message - determines mode, starts async initialization
364066
+ * 3. control_request - fire-and-forget, tracked by dispatcher
364067
+ * 4. control_cancel - synchronous
364068
+ * 5. user_message - enqueued for processing
364069
+ */
363404
364070
  async run() {
363405
364071
  try {
363406
364072
  if (this.debugMode) {
363407
364073
  console.error("[Session] Starting session", this.sessionId);
363408
364074
  }
363409
364075
  if (this.initialPrompt !== null) {
363410
- const handled = await this.handleFirstMessage(this.initialPrompt);
363411
- if (handled && this.isShuttingDown) {
363412
- await this.shutdown();
363413
- return;
363414
- }
364076
+ this.handleFirstMessage(this.initialPrompt);
363415
364077
  }
363416
364078
  try {
363417
364079
  for await (const message of this.inputReader.read()) {
363418
364080
  if (this.abortController.signal.aborted) {
363419
364081
  break;
363420
364082
  }
364083
+ if (isControlResponse(message)) {
364084
+ this.handleControlResponse(message);
364085
+ continue;
364086
+ }
363421
364087
  if (this.controlSystemEnabled === null) {
363422
- const handled = await this.handleFirstMessage(message);
363423
- if (handled) {
363424
- if (this.isShuttingDown) {
363425
- break;
363426
- }
363427
- continue;
363428
- }
364088
+ this.handleFirstMessage(message);
364089
+ continue;
363429
364090
  }
363430
364091
  if (isControlRequest(message)) {
363431
- await this.handleControlRequest(message);
363432
- } else if (isControlResponse(message)) {
363433
- this.handleControlResponse(message);
364092
+ this.handleControlRequestAsync(message);
363434
364093
  } else if (isControlCancel(message)) {
363435
364094
  this.handleControlCancel(message);
363436
364095
  } else if (isCLIUserMessage(message)) {
@@ -363453,18 +364112,7 @@ var Session2 = class {
363453
364112
  }
363454
364113
  throw streamError;
363455
364114
  }
363456
- while (this.processingPromise) {
363457
- if (this.debugMode) {
363458
- console.error("[Session] Waiting for final processing to complete");
363459
- }
363460
- try {
363461
- await this.processingPromise;
363462
- } catch (error2) {
363463
- if (this.debugMode) {
363464
- console.error("[Session] Error in final processing:", error2);
363465
- }
363466
- }
363467
- }
364115
+ await this.waitForAllPendingWork();
363468
364116
  await this.shutdown();
363469
364117
  } catch (error2) {
363470
364118
  if (this.debugMode) {
@@ -394598,7 +395246,9 @@ var useAuthCommand = /* @__PURE__ */ __name((settings, config2, addItem) => {
394598
395246
  addItem(
394599
395247
  {
394600
395248
  type: "info" /* INFO */,
394601
- text: `Authenticated successfully with ${authType} credentials.`
395249
+ text: t3("Authenticated successfully with {{authType}} credentials.", {
395250
+ authType
395251
+ })
394602
395252
  },
394603
395253
  Date.now()
394604
395254
  );
@@ -394635,7 +395285,9 @@ var useAuthCommand = /* @__PURE__ */ __name((settings, config2, addItem) => {
394635
395285
  addItem(
394636
395286
  {
394637
395287
  type: "info" /* INFO */,
394638
- text: `Authenticated successfully with ${authType} credentials.`
395288
+ text: t3("Authenticated successfully with {{authType}} credentials.", {
395289
+ authType
395290
+ })
394639
395291
  },
394640
395292
  Date.now()
394641
395293
  );
@@ -405346,7 +405998,7 @@ var homeDirectoryCheck = {
405346
405998
  fs110.realpath(os47.homedir())
405347
405999
  ]);
405348
406000
  if (workspaceRealPath === homeRealPath) {
405349
- return "\u5F53\u524D\u6B63\u5728 ~ \u76EE\u5F55\u4E0B\u8FD0\u884C RDMind\uFF0C\u5EFA\u8BAE\u8FDB\u5165\u9879\u76EE\u76EE\u5F55";
406001
+ return "\u5F53\u524D\u6B63\u5728\u4E3B\u76EE\u5F55\u4E0B\u8FD0\u884C RDMind\uFF0C\u5EFA\u8BAE\u8FDB\u5165\u9879\u76EE\u76EE\u5F55";
405350
406002
  }
405351
406003
  return null;
405352
406004
  } catch (_err) {
@@ -407874,7 +408526,7 @@ var GeminiAgent = class {
407874
408526
  name: APPROVAL_MODE_INFO[mode].name,
407875
408527
  description: APPROVAL_MODE_INFO[mode].description
407876
408528
  }));
407877
- const version3 = "0.1.3-alpha.6";
408529
+ const version3 = "0.1.4-alpha.0";
407878
408530
  return {
407879
408531
  protocolVersion: PROTOCOL_VERSION,
407880
408532
  agentInfo: {
@@ -408214,8 +408866,9 @@ async function main() {
408214
408866
  process.exit(1);
408215
408867
  }
408216
408868
  }
408869
+ const inputFormat = argv.inputFormat;
408217
408870
  let stdinData = "";
408218
- if (!process.stdin.isTTY) {
408871
+ if (!process.stdin.isTTY && inputFormat !== "stream-json") {
408219
408872
  stdinData = await readStdin();
408220
408873
  }
408221
408874
  const injectStdinIntoArgs = /* @__PURE__ */ __name((args, stdinData2) => {
@@ -408471,12 +409124,12 @@ main().catch((error2) => {
408471
409124
  */
408472
409125
  /**
408473
409126
  * @license
408474
- * Copyright 2025 RDMind
409127
+ * Copyright 2025 Qwen Team
408475
409128
  * SPDX-License-Identifier: Apache-2.0
408476
409129
  */
408477
409130
  /**
408478
409131
  * @license
408479
- * Copyright 2025 Qwen Team
409132
+ * Copyright 2025 RDMind
408480
409133
  * SPDX-License-Identifier: Apache-2.0
408481
409134
  */
408482
409135
  /*! Bundled license information: