@rdmind/rdmind 0.1.3-alpha.6 → 0.1.3

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 +778 -145
  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
  }
@@ -160787,7 +160785,7 @@ function createContentGeneratorConfig(config2, authType, generationConfig) {
160787
160785
  };
160788
160786
  }
160789
160787
  async function createContentGenerator(config2, gcConfig, isInitialAuth) {
160790
- const version3 = "0.1.3-alpha.6";
160788
+ const version3 = "0.1.3";
160791
160789
  const userAgent2 = `QwenCode/${version3} (${process.platform}; ${process.arch})`;
160792
160790
  const baseHeaders = {
160793
160791
  "User-Agent": userAgent2
@@ -214581,6 +214579,119 @@ var init_sa_impersonation_provider = __esm({
214581
214579
  }
214582
214580
  });
214583
214581
 
214582
+ // packages/core/src/tools/sdk-control-client-transport.ts
214583
+ var SdkControlClientTransport;
214584
+ var init_sdk_control_client_transport = __esm({
214585
+ "packages/core/src/tools/sdk-control-client-transport.ts"() {
214586
+ "use strict";
214587
+ init_esbuild_shims();
214588
+ SdkControlClientTransport = class {
214589
+ static {
214590
+ __name(this, "SdkControlClientTransport");
214591
+ }
214592
+ serverName;
214593
+ sendMcpMessage;
214594
+ debugMode;
214595
+ started = false;
214596
+ // Transport interface callbacks
214597
+ onmessage;
214598
+ onerror;
214599
+ onclose;
214600
+ constructor(options2) {
214601
+ this.serverName = options2.serverName;
214602
+ this.sendMcpMessage = options2.sendMcpMessage;
214603
+ this.debugMode = options2.debugMode ?? false;
214604
+ }
214605
+ /**
214606
+ * Start the transport
214607
+ * For SDK transport, this just marks it as ready - no subprocess to spawn
214608
+ */
214609
+ async start() {
214610
+ if (this.started) {
214611
+ return;
214612
+ }
214613
+ this.started = true;
214614
+ if (this.debugMode) {
214615
+ console.error(
214616
+ `[SdkControlClientTransport] Started for server '${this.serverName}'`
214617
+ );
214618
+ }
214619
+ }
214620
+ /**
214621
+ * Send a message to the SDK MCP server via control plane
214622
+ *
214623
+ * Routes the message through the control plane and delivers
214624
+ * the response via onmessage callback.
214625
+ */
214626
+ async send(message) {
214627
+ if (!this.started) {
214628
+ throw new Error(
214629
+ `SdkControlClientTransport (${this.serverName}) not started. Call start() first.`
214630
+ );
214631
+ }
214632
+ if (this.debugMode) {
214633
+ console.error(
214634
+ `[SdkControlClientTransport] Sending message to '${this.serverName}':`,
214635
+ JSON.stringify(message)
214636
+ );
214637
+ }
214638
+ try {
214639
+ const response = await this.sendMcpMessage(this.serverName, message);
214640
+ if (this.debugMode) {
214641
+ console.error(
214642
+ `[SdkControlClientTransport] Received response from '${this.serverName}':`,
214643
+ JSON.stringify(response)
214644
+ );
214645
+ }
214646
+ if (this.onmessage) {
214647
+ this.onmessage(response);
214648
+ }
214649
+ } catch (error2) {
214650
+ if (this.debugMode) {
214651
+ console.error(
214652
+ `[SdkControlClientTransport] Error sending to '${this.serverName}':`,
214653
+ error2
214654
+ );
214655
+ }
214656
+ if (this.onerror) {
214657
+ this.onerror(error2 instanceof Error ? error2 : new Error(String(error2)));
214658
+ }
214659
+ throw error2;
214660
+ }
214661
+ }
214662
+ /**
214663
+ * Close the transport
214664
+ */
214665
+ async close() {
214666
+ if (!this.started) {
214667
+ return;
214668
+ }
214669
+ this.started = false;
214670
+ if (this.debugMode) {
214671
+ console.error(
214672
+ `[SdkControlClientTransport] Closed for server '${this.serverName}'`
214673
+ );
214674
+ }
214675
+ if (this.onclose) {
214676
+ this.onclose();
214677
+ }
214678
+ }
214679
+ /**
214680
+ * Check if transport is started
214681
+ */
214682
+ isStarted() {
214683
+ return this.started;
214684
+ }
214685
+ /**
214686
+ * Get server name
214687
+ */
214688
+ getServerName() {
214689
+ return this.serverName;
214690
+ }
214691
+ };
214692
+ }
214693
+ });
214694
+
214584
214695
  // packages/core/src/utils/secure-browser-launcher.ts
214585
214696
  import { execFile as execFile8 } from "node:child_process";
214586
214697
  import { promisify as promisify7 } from "node:util";
@@ -215932,7 +216043,7 @@ function populateMcpServerCommand(mcpServers, mcpServerCommand) {
215932
216043
  }
215933
216044
  return mcpServers;
215934
216045
  }
215935
- async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext, cliConfig) {
216046
+ async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext, cliConfig, sendSdkMcpMessage) {
215936
216047
  updateMCPServerStatus(mcpServerName, "connecting" /* CONNECTING */);
215937
216048
  let mcpClient;
215938
216049
  try {
@@ -215940,7 +216051,8 @@ async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry,
215940
216051
  mcpServerName,
215941
216052
  mcpServerConfig,
215942
216053
  debugMode,
215943
- workspaceContext
216054
+ workspaceContext,
216055
+ sendSdkMcpMessage
215944
216056
  );
215945
216057
  mcpClient.onerror = (error2) => {
215946
216058
  console.error(`MCP ERROR (${mcpServerName}):`, error2.toString());
@@ -216074,7 +216186,7 @@ async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, promptParam
216074
216186
  function hasNetworkTransport(config2) {
216075
216187
  return !!(config2.url || config2.httpUrl);
216076
216188
  }
216077
- async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext) {
216189
+ async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext, sendSdkMcpMessage) {
216078
216190
  const mcpClient = new Client({
216079
216191
  name: "qwen-code-mcp-client",
216080
216192
  version: "0.0.1"
@@ -216116,7 +216228,8 @@ async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, wor
216116
216228
  const transport = await createTransport(
216117
216229
  mcpServerName,
216118
216230
  mcpServerConfig,
216119
- debugMode
216231
+ debugMode,
216232
+ sendSdkMcpMessage
216120
216233
  );
216121
216234
  try {
216122
216235
  await mcpClient.connect(transport, {
@@ -216416,7 +216529,19 @@ async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, wor
216416
216529
  }
216417
216530
  }
216418
216531
  }
216419
- async function createTransport(mcpServerName, mcpServerConfig, debugMode) {
216532
+ async function createTransport(mcpServerName, mcpServerConfig, debugMode, sendSdkMcpMessage) {
216533
+ if (isSdkMcpServerConfig(mcpServerConfig)) {
216534
+ if (!sendSdkMcpMessage) {
216535
+ throw new Error(
216536
+ `SDK MCP server '${mcpServerName}' requires sendSdkMcpMessage callback`
216537
+ );
216538
+ }
216539
+ return new SdkControlClientTransport({
216540
+ serverName: mcpServerName,
216541
+ sendMcpMessage: sendSdkMcpMessage,
216542
+ debugMode
216543
+ });
216544
+ }
216420
216545
  if (mcpServerConfig.authProviderType === "service_account_impersonation" /* SERVICE_ACCOUNT_IMPERSONATION */) {
216421
216546
  const provider = new ServiceAccountImpersonationProvider(mcpServerConfig);
216422
216547
  const transportOptions = {
@@ -216578,6 +216703,7 @@ var init_mcp_client = __esm({
216578
216703
  init_google_auth_provider();
216579
216704
  init_sa_impersonation_provider();
216580
216705
  init_mcp_tool();
216706
+ init_sdk_control_client_transport();
216581
216707
  init_node();
216582
216708
  init_oauth_provider();
216583
216709
  init_oauth_token_storage();
@@ -216597,13 +216723,14 @@ var init_mcp_client = __esm({
216597
216723
  return MCPDiscoveryState2;
216598
216724
  })(MCPDiscoveryState || {});
216599
216725
  McpClient = class {
216600
- constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode) {
216726
+ constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode, sendSdkMcpMessage) {
216601
216727
  this.serverName = serverName;
216602
216728
  this.serverConfig = serverConfig;
216603
216729
  this.toolRegistry = toolRegistry;
216604
216730
  this.promptRegistry = promptRegistry;
216605
216731
  this.workspaceContext = workspaceContext;
216606
216732
  this.debugMode = debugMode;
216733
+ this.sendSdkMcpMessage = sendSdkMcpMessage;
216607
216734
  this.client = new Client({
216608
216735
  name: `rdmind-cli-mcp-client-${this.serverName}`,
216609
216736
  version: "0.0.1"
@@ -216693,7 +216820,12 @@ var init_mcp_client = __esm({
216693
216820
  updateMCPServerStatus(this.serverName, status);
216694
216821
  }
216695
216822
  async createTransport() {
216696
- return createTransport(this.serverName, this.serverConfig, this.debugMode);
216823
+ return createTransport(
216824
+ this.serverName,
216825
+ this.serverConfig,
216826
+ this.debugMode,
216827
+ this.sendSdkMcpMessage
216828
+ );
216697
216829
  }
216698
216830
  async discoverTools(cliConfig) {
216699
216831
  return discoverTools(
@@ -216739,6 +216871,7 @@ var init_mcp_client_manager = __esm({
216739
216871
  "packages/core/src/tools/mcp-client-manager.ts"() {
216740
216872
  "use strict";
216741
216873
  init_esbuild_shims();
216874
+ init_config3();
216742
216875
  init_mcp_client();
216743
216876
  init_errors();
216744
216877
  McpClientManager = class {
@@ -216754,7 +216887,8 @@ var init_mcp_client_manager = __esm({
216754
216887
  workspaceContext;
216755
216888
  discoveryState = "not_started" /* NOT_STARTED */;
216756
216889
  eventEmitter;
216757
- constructor(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext, eventEmitter) {
216890
+ sendSdkMcpMessage;
216891
+ constructor(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext, eventEmitter, sendSdkMcpMessage) {
216758
216892
  this.mcpServers = mcpServers;
216759
216893
  this.mcpServerCommand = mcpServerCommand;
216760
216894
  this.toolRegistry = toolRegistry;
@@ -216762,6 +216896,7 @@ var init_mcp_client_manager = __esm({
216762
216896
  this.debugMode = debugMode;
216763
216897
  this.workspaceContext = workspaceContext;
216764
216898
  this.eventEmitter = eventEmitter;
216899
+ this.sendSdkMcpMessage = sendSdkMcpMessage;
216765
216900
  }
216766
216901
  /**
216767
216902
  * Initiates the tool discovery process for all configured MCP servers.
@@ -216781,13 +216916,15 @@ var init_mcp_client_manager = __esm({
216781
216916
  this.eventEmitter?.emit("mcp-client-update", this.clients);
216782
216917
  const discoveryPromises = Object.entries(servers).map(
216783
216918
  async ([name3, config2]) => {
216919
+ const sdkCallback = isSdkMcpServerConfig(config2) ? this.sendSdkMcpMessage : void 0;
216784
216920
  const client = new McpClient(
216785
216921
  name3,
216786
216922
  config2,
216787
216923
  this.toolRegistry,
216788
216924
  this.promptRegistry,
216789
216925
  this.workspaceContext,
216790
- this.debugMode
216926
+ this.debugMode,
216927
+ sdkCallback
216791
216928
  );
216792
216929
  this.clients.set(name3, client);
216793
216930
  this.eventEmitter?.emit("mcp-client-update", this.clients);
@@ -216974,7 +217111,7 @@ Signal: Signal number or \`(none)\` if no signal was received.
216974
217111
  tools = /* @__PURE__ */ new Map();
216975
217112
  config;
216976
217113
  mcpClientManager;
216977
- constructor(config2, eventEmitter) {
217114
+ constructor(config2, eventEmitter, sendSdkMcpMessage) {
216978
217115
  this.config = config2;
216979
217116
  this.mcpClientManager = new McpClientManager(
216980
217117
  this.config.getMcpServers() ?? {},
@@ -216983,7 +217120,8 @@ Signal: Signal number or \`(none)\` if no signal was received.
216983
217120
  this.config.getPromptRegistry(),
216984
217121
  this.config.getDebugMode(),
216985
217122
  this.config.getWorkspaceContext(),
216986
- eventEmitter
217123
+ eventEmitter,
217124
+ sendSdkMcpMessage
216987
217125
  );
216988
217126
  }
216989
217127
  /**
@@ -225625,6 +225763,9 @@ var init_workspaceContext = __esm({
225625
225763
  import * as path54 from "node:path";
225626
225764
  import process12 from "node:process";
225627
225765
  import { randomUUID as randomUUID6 } from "node:crypto";
225766
+ function isSdkMcpServerConfig(config2) {
225767
+ return config2.type === "sdk";
225768
+ }
225628
225769
  function normalizeConfigOutputFormat(format4) {
225629
225770
  if (!format4) {
225630
225771
  return void 0;
@@ -225723,7 +225864,7 @@ var init_config3 = __esm({
225723
225864
  DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD = 25e3;
225724
225865
  DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES = 1e3;
225725
225866
  MCPServerConfig = class {
225726
- constructor(command2, args, env7, cwd7, url3, httpUrl, headers, tcp, timeout2, trust, description, includeTools, excludeTools, extensionName, oauth, authProviderType, targetAudience, targetServiceAccount) {
225867
+ constructor(command2, args, env7, cwd7, url3, httpUrl, headers, tcp, timeout2, trust, description, includeTools, excludeTools, extensionName, oauth, authProviderType, targetAudience, targetServiceAccount, type) {
225727
225868
  this.command = command2;
225728
225869
  this.args = args;
225729
225870
  this.env = env7;
@@ -225742,11 +225883,13 @@ var init_config3 = __esm({
225742
225883
  this.authProviderType = authProviderType;
225743
225884
  this.targetAudience = targetAudience;
225744
225885
  this.targetServiceAccount = targetServiceAccount;
225886
+ this.type = type;
225745
225887
  }
225746
225888
  static {
225747
225889
  __name(this, "MCPServerConfig");
225748
225890
  }
225749
225891
  };
225892
+ __name(isSdkMcpServerConfig, "isSdkMcpServerConfig");
225750
225893
  AuthProviderType = /* @__PURE__ */ ((AuthProviderType2) => {
225751
225894
  AuthProviderType2["DYNAMIC_DISCOVERY"] = "dynamic_discovery";
225752
225895
  AuthProviderType2["GOOGLE_CREDENTIALS"] = "google_credentials";
@@ -225963,8 +226106,9 @@ var init_config3 = __esm({
225963
226106
  }
225964
226107
  /**
225965
226108
  * Must only be called once, throws if called again.
226109
+ * @param options Optional initialization options including sendSdkMcpMessage callback
225966
226110
  */
225967
- async initialize() {
226111
+ async initialize(options2) {
225968
226112
  if (this.initialized) {
225969
226113
  throw Error("Config was already initialized");
225970
226114
  }
@@ -225978,7 +226122,9 @@ var init_config3 = __esm({
225978
226122
  if (this.sessionSubagents.length > 0) {
225979
226123
  this.subagentManager.loadSessionSubagents(this.sessionSubagents);
225980
226124
  }
225981
- this.toolRegistry = await this.createToolRegistry();
226125
+ this.toolRegistry = await this.createToolRegistry(
226126
+ options2?.sendSdkMcpMessage
226127
+ );
225982
226128
  await this.geminiClient.initialize();
225983
226129
  logStartSession(this, new StartSessionEvent(this));
225984
226130
  }
@@ -226447,8 +226593,12 @@ var init_config3 = __esm({
226447
226593
  getSubagentManager() {
226448
226594
  return this.subagentManager;
226449
226595
  }
226450
- async createToolRegistry() {
226451
- const registry2 = new ToolRegistry(this, this.eventEmitter);
226596
+ async createToolRegistry(sendSdkMcpMessage) {
226597
+ const registry2 = new ToolRegistry(
226598
+ this,
226599
+ this.eventEmitter,
226600
+ sendSdkMcpMessage
226601
+ );
226452
226602
  const coreToolsConfig = this.getCoreTools();
226453
226603
  const excludeToolsConfig = this.getExcludeTools();
226454
226604
  const registerCoreTool = /* @__PURE__ */ __name((ToolClass, ...args) => {
@@ -226519,6 +226669,7 @@ var init_config3 = __esm({
226519
226669
  registerCoreTool(WebSearchTool, this);
226520
226670
  }
226521
226671
  await registry2.discoverAllTools();
226672
+ console.debug("ToolRegistry created", registry2.getAllToolNames());
226522
226673
  return registry2;
226523
226674
  }
226524
226675
  };
@@ -235631,7 +235782,9 @@ var init_src2 = __esm({
235631
235782
  init_read_many_files();
235632
235783
  init_read_knowledge_ext();
235633
235784
  init_mcp_client();
235785
+ init_mcp_client_manager();
235634
235786
  init_mcp_tool();
235787
+ init_sdk_control_client_transport();
235635
235788
  init_task();
235636
235789
  init_todoWrite();
235637
235790
  init_exitPlanMode();
@@ -235778,8 +235931,8 @@ var init_git_commit = __esm({
235778
235931
  "packages/core/src/generated/git-commit.ts"() {
235779
235932
  "use strict";
235780
235933
  init_esbuild_shims();
235781
- GIT_COMMIT_INFO = "72a170b5";
235782
- CLI_VERSION = "0.1.3-alpha.6";
235934
+ GIT_COMMIT_INFO = "aeac6827";
235935
+ CLI_VERSION = "0.1.3";
235783
235936
  }
235784
235937
  });
235785
235938
 
@@ -236781,6 +236934,7 @@ __export(core_exports4, {
236781
236934
  MUTATOR_KINDS: () => MUTATOR_KINDS,
236782
236935
  MarkdownParser: () => MarkdownParser,
236783
236936
  McpClient: () => McpClient,
236937
+ McpClientManager: () => McpClientManager,
236784
236938
  MemoryMetricType: () => MemoryMetricType,
236785
236939
  MemoryTool: () => MemoryTool,
236786
236940
  MessageSenderType: () => MessageSenderType,
@@ -236817,6 +236971,7 @@ __export(core_exports4, {
236817
236971
  SUPPORTED_IMAGE_MIME_TYPES: () => SUPPORTED_IMAGE_MIME_TYPES,
236818
236972
  SYSTEM_FILE_EXCLUDES: () => SYSTEM_FILE_EXCLUDES,
236819
236973
  SchemaValidator: () => SchemaValidator,
236974
+ SdkControlClientTransport: () => SdkControlClientTransport,
236820
236975
  SemanticAttributes: () => SemanticAttributes,
236821
236976
  SessionService: () => SessionService,
236822
236977
  ShellExecutionService: () => ShellExecutionService,
@@ -236976,6 +237131,7 @@ __export(core_exports4, {
236976
237131
  isQwenQuotaExceededError: () => isQwenQuotaExceededError,
236977
237132
  isQwenThrottlingError: () => isQwenThrottlingError,
236978
237133
  isSchemaDepthError: () => isSchemaDepthError,
237134
+ isSdkMcpServerConfig: () => isSdkMcpServerConfig,
236979
237135
  isStructuredError: () => isStructuredError,
236980
237136
  isSubpath: () => isSubpath,
236981
237137
  isSupportedImageMimeType: () => isSupportedImageMimeType,
@@ -346248,7 +346404,7 @@ __name(getPackageJson, "getPackageJson");
346248
346404
  // packages/cli/src/utils/version.ts
346249
346405
  async function getCliVersion() {
346250
346406
  const pkgJson = await getPackageJson();
346251
- return "0.1.3-alpha.6";
346407
+ return "0.1.3";
346252
346408
  }
346253
346409
  __name(getCliVersion, "getCliVersion");
346254
346410
 
@@ -352615,7 +352771,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
352615
352771
 
352616
352772
  // packages/cli/src/generated/git-commit.ts
352617
352773
  init_esbuild_shims();
352618
- var GIT_COMMIT_INFO2 = "72a170b5";
352774
+ var GIT_COMMIT_INFO2 = "aeac6827";
352619
352775
 
352620
352776
  // packages/cli/src/utils/systemInfo.ts
352621
352777
  async function getNpmVersion() {
@@ -355464,21 +355620,17 @@ This is a **NON-NEGOTIABLE** requirement. Even if the user writes in English, sa
355464
355620
 
355465
355621
  **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
355622
 
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
355623
  ## Examples
355470
355624
 
355471
355625
  ### \u2705 CORRECT:
355472
355626
  - User says "hi" \u2192 Respond in ${language} (e.g., "Bonjour" if ${language} is French)
355473
355627
  - Tool result \u2192 "\u5DF2\u6210\u529F\u8BFB\u53D6\u6587\u4EF6 config.json" (if ${language} is Chinese)
355474
355628
  - 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
355629
 
355477
355630
  ### \u274C WRONG:
355478
355631
  - User says "hi" \u2192 "Hello" in English
355479
355632
  - Tool result \u2192 "Successfully read file" in English
355480
355633
  - Error \u2192 "File not found" in English
355481
- - Thinking content \u2192 "I'm analyzing the user's question..." in English
355482
355634
 
355483
355635
  ## Notes
355484
355636
 
@@ -362133,11 +362285,30 @@ var BaseController = class {
362133
362285
  * Send an outgoing control request to SDK
362134
362286
  *
362135
362287
  * Manages lifecycle: register -> send -> wait for response -> deregister
362288
+ * Respects the provided AbortSignal for cancellation.
362136
362289
  */
362137
- async sendControlRequest(payload, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) {
362290
+ async sendControlRequest(payload, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS, signal) {
362291
+ if (signal?.aborted) {
362292
+ throw new Error("Request aborted");
362293
+ }
362138
362294
  const requestId = randomUUID9();
362139
362295
  return new Promise((resolve26, reject) => {
362296
+ const abortHandler = /* @__PURE__ */ __name(() => {
362297
+ this.registry.deregisterOutgoingRequest(requestId);
362298
+ reject(new Error("Request aborted"));
362299
+ if (this.context.debugMode) {
362300
+ console.error(
362301
+ `[${this.controllerName}] Outgoing request aborted: ${requestId}`
362302
+ );
362303
+ }
362304
+ }, "abortHandler");
362305
+ if (signal) {
362306
+ signal.addEventListener("abort", abortHandler, { once: true });
362307
+ }
362140
362308
  const timeoutId = setTimeout(() => {
362309
+ if (signal) {
362310
+ signal.removeEventListener("abort", abortHandler);
362311
+ }
362141
362312
  this.registry.deregisterOutgoingRequest(requestId);
362142
362313
  reject(new Error("Control request timeout"));
362143
362314
  if (this.context.debugMode) {
@@ -362146,11 +362317,23 @@ var BaseController = class {
362146
362317
  );
362147
362318
  }
362148
362319
  }, timeoutMs);
362320
+ const wrappedResolve = /* @__PURE__ */ __name((response) => {
362321
+ if (signal) {
362322
+ signal.removeEventListener("abort", abortHandler);
362323
+ }
362324
+ resolve26(response);
362325
+ }, "wrappedResolve");
362326
+ const wrappedReject = /* @__PURE__ */ __name((error2) => {
362327
+ if (signal) {
362328
+ signal.removeEventListener("abort", abortHandler);
362329
+ }
362330
+ reject(error2);
362331
+ }, "wrappedReject");
362149
362332
  this.registry.registerOutgoingRequest(
362150
362333
  requestId,
362151
362334
  this.controllerName,
362152
- resolve26,
362153
- reject,
362335
+ wrappedResolve,
362336
+ wrappedReject,
362154
362337
  timeoutId
362155
362338
  );
362156
362339
  const request4 = {
@@ -362161,6 +362344,9 @@ var BaseController = class {
362161
362344
  try {
362162
362345
  this.context.streamJson.send(request4);
362163
362346
  } catch (error2) {
362347
+ if (signal) {
362348
+ signal.removeEventListener("abort", abortHandler);
362349
+ }
362164
362350
  this.registry.deregisterOutgoingRequest(requestId);
362165
362351
  reject(error2);
362166
362352
  }
@@ -362174,6 +362360,7 @@ var BaseController = class {
362174
362360
  };
362175
362361
 
362176
362362
  // packages/cli/src/nonInteractive/control/controllers/systemController.ts
362363
+ init_core4();
362177
362364
  var SystemController = class extends BaseController {
362178
362365
  static {
362179
362366
  __name(this, "SystemController");
@@ -362181,16 +362368,25 @@ var SystemController = class extends BaseController {
362181
362368
  /**
362182
362369
  * Handle system control requests
362183
362370
  */
362184
- async handleRequestPayload(payload, _signal) {
362371
+ async handleRequestPayload(payload, signal) {
362372
+ if (signal.aborted) {
362373
+ throw new Error("Request aborted");
362374
+ }
362185
362375
  switch (payload.subtype) {
362186
362376
  case "initialize":
362187
- return this.handleInitialize(payload);
362377
+ return this.handleInitialize(
362378
+ payload,
362379
+ signal
362380
+ );
362188
362381
  case "interrupt":
362189
362382
  return this.handleInterrupt();
362190
362383
  case "set_model":
362191
- return this.handleSetModel(payload);
362384
+ return this.handleSetModel(
362385
+ payload,
362386
+ signal
362387
+ );
362192
362388
  case "supported_commands":
362193
- return this.handleSupportedCommands();
362389
+ return this.handleSupportedCommands(signal);
362194
362390
  default:
362195
362391
  throw new Error(`Unsupported request subtype in SystemController`);
362196
362392
  }
@@ -362198,41 +362394,108 @@ var SystemController = class extends BaseController {
362198
362394
  /**
362199
362395
  * Handle initialize request
362200
362396
  *
362201
- * Registers SDK MCP servers and returns capabilities
362397
+ * Processes SDK MCP servers config.
362398
+ * SDK servers are registered in context.sdkMcpServers
362399
+ * and added to config.mcpServers with the sdk type flag.
362400
+ * External MCP servers are configured separately in settings.
362202
362401
  */
362203
- async handleInitialize(payload) {
362402
+ async handleInitialize(payload, signal) {
362403
+ if (signal.aborted) {
362404
+ throw new Error("Request aborted");
362405
+ }
362204
362406
  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);
362407
+ if (payload.sdkMcpServers && typeof payload.sdkMcpServers === "object" && payload.sdkMcpServers !== null) {
362408
+ const sdkServers = {};
362409
+ for (const [key, wireConfig] of Object.entries(payload.sdkMcpServers)) {
362410
+ const name3 = typeof wireConfig?.name === "string" && wireConfig.name.trim().length ? wireConfig.name : key;
362411
+ this.context.sdkMcpServers.add(name3);
362412
+ sdkServers[name3] = new MCPServerConfig(
362413
+ void 0,
362414
+ // command
362415
+ void 0,
362416
+ // args
362417
+ void 0,
362418
+ // env
362419
+ void 0,
362420
+ // cwd
362421
+ void 0,
362422
+ // url
362423
+ void 0,
362424
+ // httpUrl
362425
+ void 0,
362426
+ // headers
362427
+ void 0,
362428
+ // tcp
362429
+ void 0,
362430
+ // timeout
362431
+ true,
362432
+ // trust - SDK servers are trusted
362433
+ void 0,
362434
+ // description
362435
+ void 0,
362436
+ // includeTools
362437
+ void 0,
362438
+ // excludeTools
362439
+ void 0,
362440
+ // extensionName
362441
+ void 0,
362442
+ // oauth
362443
+ void 0,
362444
+ // authProviderType
362445
+ void 0,
362446
+ // targetAudience
362447
+ void 0,
362448
+ // targetServiceAccount
362449
+ "sdk"
362450
+ // type
362451
+ );
362208
362452
  }
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
- );
362453
+ const sdkServerCount = Object.keys(sdkServers).length;
362454
+ if (sdkServerCount > 0) {
362455
+ try {
362456
+ this.context.config.addMcpServers(sdkServers);
362457
+ if (this.context.debugMode) {
362458
+ console.error(
362459
+ `[SystemController] Added ${sdkServerCount} SDK MCP servers to config`
362460
+ );
362461
+ }
362462
+ } catch (error2) {
362463
+ if (this.context.debugMode) {
362464
+ console.error(
362465
+ "[SystemController] Failed to add SDK MCP servers:",
362466
+ error2
362467
+ );
362468
+ }
362222
362469
  }
362223
362470
  }
362224
362471
  }
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
- );
362472
+ if (payload.mcpServers && typeof payload.mcpServers === "object" && payload.mcpServers !== null) {
362473
+ const externalServers = {};
362474
+ for (const [name3, serverConfig] of Object.entries(payload.mcpServers)) {
362475
+ const normalized2 = this.normalizeMcpServerConfig(
362476
+ name3,
362477
+ serverConfig
362478
+ );
362479
+ if (normalized2) {
362480
+ externalServers[name3] = normalized2;
362232
362481
  }
362233
- } catch (error2) {
362234
- if (this.context.debugMode) {
362235
- console.error("[SystemController] Failed to add MCP servers:", error2);
362482
+ }
362483
+ const externalCount = Object.keys(externalServers).length;
362484
+ if (externalCount > 0) {
362485
+ try {
362486
+ this.context.config.addMcpServers(externalServers);
362487
+ if (this.context.debugMode) {
362488
+ console.error(
362489
+ `[SystemController] Added ${externalCount} external MCP servers to config`
362490
+ );
362491
+ }
362492
+ } catch (error2) {
362493
+ if (this.context.debugMode) {
362494
+ console.error(
362495
+ "[SystemController] Failed to add external MCP servers:",
362496
+ error2
362497
+ );
362498
+ }
362236
362499
  }
362237
362500
  }
362238
362501
  }
@@ -362277,11 +362540,80 @@ var SystemController = class extends BaseController {
362277
362540
  can_handle_hook_callback: false,
362278
362541
  can_set_permission_mode: typeof this.context.config.setApprovalMode === "function",
362279
362542
  can_set_model: typeof this.context.config.setModel === "function",
362280
- /* TODO: sdkMcpServers support */
362281
- can_handle_mcp_message: false
362543
+ // SDK MCP servers are supported - messages routed through control plane
362544
+ can_handle_mcp_message: true
362282
362545
  };
362283
362546
  return capabilities;
362284
362547
  }
362548
+ normalizeMcpServerConfig(serverName, config2) {
362549
+ if (!config2 || typeof config2 !== "object") {
362550
+ if (this.context.debugMode) {
362551
+ console.error(
362552
+ `[SystemController] Ignoring invalid MCP server config for '${serverName}'`
362553
+ );
362554
+ }
362555
+ return null;
362556
+ }
362557
+ const authProvider = this.normalizeAuthProviderType(
362558
+ config2.authProviderType
362559
+ );
362560
+ const oauthConfig = this.normalizeOAuthConfig(config2.oauth);
362561
+ return new MCPServerConfig(
362562
+ config2.command,
362563
+ config2.args,
362564
+ config2.env,
362565
+ config2.cwd,
362566
+ config2.url,
362567
+ config2.httpUrl,
362568
+ config2.headers,
362569
+ config2.tcp,
362570
+ config2.timeout,
362571
+ config2.trust,
362572
+ config2.description,
362573
+ config2.includeTools,
362574
+ config2.excludeTools,
362575
+ config2.extensionName,
362576
+ oauthConfig,
362577
+ authProvider,
362578
+ config2.targetAudience,
362579
+ config2.targetServiceAccount
362580
+ );
362581
+ }
362582
+ normalizeAuthProviderType(value) {
362583
+ if (!value) {
362584
+ return void 0;
362585
+ }
362586
+ switch (value) {
362587
+ case "dynamic_discovery" /* DYNAMIC_DISCOVERY */:
362588
+ case "google_credentials" /* GOOGLE_CREDENTIALS */:
362589
+ case "service_account_impersonation" /* SERVICE_ACCOUNT_IMPERSONATION */:
362590
+ return value;
362591
+ default:
362592
+ if (this.context.debugMode) {
362593
+ console.error(
362594
+ `[SystemController] Unsupported authProviderType '${value}', skipping`
362595
+ );
362596
+ }
362597
+ return void 0;
362598
+ }
362599
+ }
362600
+ normalizeOAuthConfig(oauth) {
362601
+ if (!oauth) {
362602
+ return void 0;
362603
+ }
362604
+ return {
362605
+ enabled: oauth.enabled,
362606
+ clientId: oauth.clientId,
362607
+ clientSecret: oauth.clientSecret,
362608
+ authorizationUrl: oauth.authorizationUrl,
362609
+ tokenUrl: oauth.tokenUrl,
362610
+ scopes: oauth.scopes,
362611
+ audiences: oauth.audiences,
362612
+ redirectUri: oauth.redirectUri,
362613
+ tokenParamName: oauth.tokenParamName,
362614
+ registrationUrl: oauth.registrationUrl
362615
+ };
362616
+ }
362285
362617
  /**
362286
362618
  * Handle interrupt request
362287
362619
  *
@@ -362306,7 +362638,10 @@ var SystemController = class extends BaseController {
362306
362638
  *
362307
362639
  * Implements actual model switching with validation and error handling
362308
362640
  */
362309
- async handleSetModel(payload) {
362641
+ async handleSetModel(payload, signal) {
362642
+ if (signal.aborted) {
362643
+ throw new Error("Request aborted");
362644
+ }
362310
362645
  const model = payload.model;
362311
362646
  if (typeof model !== "string" || model.trim() === "") {
362312
362647
  throw new Error("Invalid model specified for set_model request");
@@ -362336,8 +362671,11 @@ var SystemController = class extends BaseController {
362336
362671
  *
362337
362672
  * Returns list of supported slash commands loaded dynamically
362338
362673
  */
362339
- async handleSupportedCommands() {
362340
- const slashCommands = await this.loadSlashCommandNames();
362674
+ async handleSupportedCommands(signal) {
362675
+ if (signal.aborted) {
362676
+ throw new Error("Request aborted");
362677
+ }
362678
+ const slashCommands = await this.loadSlashCommandNames(signal);
362341
362679
  return {
362342
362680
  subtype: "supported_commands",
362343
362681
  commands: slashCommands
@@ -362346,15 +362684,21 @@ var SystemController = class extends BaseController {
362346
362684
  /**
362347
362685
  * Load slash command names using CommandService
362348
362686
  *
362687
+ * @param signal - AbortSignal to respect for cancellation
362349
362688
  * @returns Promise resolving to array of slash command names
362350
362689
  */
362351
- async loadSlashCommandNames() {
362352
- const controller = new AbortController();
362690
+ async loadSlashCommandNames(signal) {
362691
+ if (signal.aborted) {
362692
+ return [];
362693
+ }
362353
362694
  try {
362354
362695
  const service = await CommandService.create(
362355
362696
  [new BuiltinCommandLoader(this.context.config)],
362356
- controller.signal
362697
+ signal
362357
362698
  );
362699
+ if (signal.aborted) {
362700
+ return [];
362701
+ }
362358
362702
  const names = /* @__PURE__ */ new Set();
362359
362703
  const commands = service.getCommands();
362360
362704
  for (const command2 of commands) {
@@ -362362,6 +362706,9 @@ var SystemController = class extends BaseController {
362362
362706
  }
362363
362707
  return Array.from(names).sort();
362364
362708
  } catch (error2) {
362709
+ if (signal.aborted) {
362710
+ return [];
362711
+ }
362365
362712
  if (this.context.debugMode) {
362366
362713
  console.error(
362367
362714
  "[SystemController] Failed to load slash commands:",
@@ -362369,8 +362716,6 @@ var SystemController = class extends BaseController {
362369
362716
  );
362370
362717
  }
362371
362718
  return [];
362372
- } finally {
362373
- controller.abort();
362374
362719
  }
362375
362720
  }
362376
362721
  };
@@ -362386,13 +362731,20 @@ var PermissionController = class extends BaseController {
362386
362731
  /**
362387
362732
  * Handle permission control requests
362388
362733
  */
362389
- async handleRequestPayload(payload, _signal) {
362734
+ async handleRequestPayload(payload, signal) {
362735
+ if (signal.aborted) {
362736
+ throw new Error("Request aborted");
362737
+ }
362390
362738
  switch (payload.subtype) {
362391
362739
  case "can_use_tool":
362392
- return this.handleCanUseTool(payload);
362740
+ return this.handleCanUseTool(
362741
+ payload,
362742
+ signal
362743
+ );
362393
362744
  case "set_permission_mode":
362394
362745
  return this.handleSetPermissionMode(
362395
- payload
362746
+ payload,
362747
+ signal
362396
362748
  );
362397
362749
  default:
362398
362750
  throw new Error(`Unsupported request subtype in PermissionController`);
@@ -362406,7 +362758,10 @@ var PermissionController = class extends BaseController {
362406
362758
  * - Tool registry validation
362407
362759
  * - Error handling with safe defaults
362408
362760
  */
362409
- async handleCanUseTool(payload) {
362761
+ async handleCanUseTool(payload, signal) {
362762
+ if (signal.aborted) {
362763
+ throw new Error("Request aborted");
362764
+ }
362410
362765
  const toolName = payload.tool_name;
362411
362766
  if (!toolName || typeof toolName !== "string" || toolName.trim().length === 0) {
362412
362767
  return {
@@ -362493,7 +362848,10 @@ var PermissionController = class extends BaseController {
362493
362848
  *
362494
362849
  * Updates the permission mode in the context
362495
362850
  */
362496
- async handleSetPermissionMode(payload) {
362851
+ async handleSetPermissionMode(payload, signal) {
362852
+ if (signal.aborted) {
362853
+ throw new Error("Request aborted");
362854
+ }
362497
362855
  const mode = payload.mode;
362498
362856
  const validModes = [
362499
362857
  "default",
@@ -362641,6 +362999,12 @@ var PermissionController = class extends BaseController {
362641
362999
  */
362642
363000
  async handleOutgoingPermissionRequest(toolCall) {
362643
363001
  try {
363002
+ if (this.context.abortSignal?.aborted) {
363003
+ await toolCall.confirmationDetails.onConfirm(
363004
+ "cancel" /* Cancel */
363005
+ );
363006
+ return;
363007
+ }
362644
363008
  const inputFormat = this.context.config.getInputFormat?.();
362645
363009
  const isStreamJsonMode = inputFormat === "stream-json" /* STREAM_JSON */;
362646
363010
  if (!isStreamJsonMode) {
@@ -362652,14 +363016,19 @@ var PermissionController = class extends BaseController {
362652
363016
  const permissionSuggestions = this.buildPermissionSuggestions(
362653
363017
  toolCall.confirmationDetails
362654
363018
  );
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
- });
363019
+ const response = await this.sendControlRequest(
363020
+ {
363021
+ subtype: "can_use_tool",
363022
+ tool_name: toolCall.request.name,
363023
+ tool_use_id: toolCall.request.callId,
363024
+ input: toolCall.request.args,
363025
+ permission_suggestions: permissionSuggestions,
363026
+ blocked_path: null
363027
+ },
363028
+ void 0,
363029
+ // use default timeout
363030
+ this.context.abortSignal
363031
+ );
362663
363032
  if (response.subtype !== "success") {
362664
363033
  await toolCall.confirmationDetails.onConfirm(
362665
363034
  "cancel" /* Cancel */
@@ -362708,6 +363077,98 @@ var PermissionController = class extends BaseController {
362708
363077
  }
362709
363078
  };
362710
363079
 
363080
+ // packages/cli/src/nonInteractive/control/controllers/sdkMcpController.ts
363081
+ init_esbuild_shims();
363082
+ var MCP_REQUEST_TIMEOUT = 3e4;
363083
+ var SdkMcpController = class extends BaseController {
363084
+ static {
363085
+ __name(this, "SdkMcpController");
363086
+ }
363087
+ /**
363088
+ * Handle SDK MCP control requests from ControlDispatcher
363089
+ *
363090
+ * Note: mcp_message requests are NOT handled here. CLI MCP clients
363091
+ * send messages via the sendSdkMcpMessage callback directly, not
363092
+ * through the control dispatcher.
363093
+ */
363094
+ async handleRequestPayload(payload, signal) {
363095
+ if (signal.aborted) {
363096
+ throw new Error("Request aborted");
363097
+ }
363098
+ switch (payload.subtype) {
363099
+ case "mcp_server_status":
363100
+ return this.handleMcpStatus();
363101
+ default:
363102
+ throw new Error(`Unsupported request subtype in SdkMcpController`);
363103
+ }
363104
+ }
363105
+ /**
363106
+ * Handle mcp_server_status request
363107
+ *
363108
+ * Returns status of all registered SDK MCP servers.
363109
+ * SDK servers are considered "connected" if they are registered.
363110
+ */
363111
+ async handleMcpStatus() {
363112
+ const status = {};
363113
+ for (const serverName of this.context.sdkMcpServers) {
363114
+ status[serverName] = "connected";
363115
+ }
363116
+ return {
363117
+ subtype: "mcp_server_status",
363118
+ status
363119
+ };
363120
+ }
363121
+ /**
363122
+ * Send MCP message to SDK server via control plane
363123
+ *
363124
+ * @param serverName - Name of the SDK MCP server
363125
+ * @param message - MCP JSON-RPC message to send
363126
+ * @returns MCP JSON-RPC response from SDK server
363127
+ */
363128
+ async sendMcpMessageToSdk(serverName, message) {
363129
+ if (this.context.debugMode) {
363130
+ console.error(
363131
+ `[SdkMcpController] Sending MCP message to SDK server '${serverName}':`,
363132
+ JSON.stringify(message)
363133
+ );
363134
+ }
363135
+ const response = await this.sendControlRequest(
363136
+ {
363137
+ subtype: "mcp_message",
363138
+ server_name: serverName,
363139
+ message
363140
+ },
363141
+ MCP_REQUEST_TIMEOUT,
363142
+ this.context.abortSignal
363143
+ );
363144
+ const responsePayload = response.response;
363145
+ const mcpResponse = responsePayload?.["mcp_response"];
363146
+ if (!mcpResponse) {
363147
+ throw new Error(
363148
+ `Invalid MCP response from SDK for server '${serverName}'`
363149
+ );
363150
+ }
363151
+ if (this.context.debugMode) {
363152
+ console.error(
363153
+ `[SdkMcpController] Received MCP response from SDK server '${serverName}':`,
363154
+ JSON.stringify(mcpResponse)
363155
+ );
363156
+ }
363157
+ return mcpResponse;
363158
+ }
363159
+ /**
363160
+ * Create a callback function for sending MCP messages to SDK servers.
363161
+ *
363162
+ * This callback is used by McpClientManager/SdkControlClientTransport to send
363163
+ * MCP messages from CLI MCP clients to SDK MCP servers via the control plane.
363164
+ *
363165
+ * @returns A function that sends MCP messages to SDK and returns the response
363166
+ */
363167
+ createSendSdkMcpMessage() {
363168
+ return (serverName, message) => this.sendMcpMessageToSdk(serverName, message);
363169
+ }
363170
+ };
363171
+
362711
363172
  // packages/cli/src/nonInteractive/control/ControlDispatcher.ts
362712
363173
  var ControlDispatcher = class {
362713
363174
  static {
@@ -362717,7 +363178,7 @@ var ControlDispatcher = class {
362717
363178
  // Make controllers publicly accessible
362718
363179
  systemController;
362719
363180
  permissionController;
362720
- // readonly mcpController: MCPController;
363181
+ sdkMcpController;
362721
363182
  // readonly hookController: HookController;
362722
363183
  // Central pending request registries
362723
363184
  pendingIncomingRequests = /* @__PURE__ */ new Map();
@@ -362734,6 +363195,11 @@ var ControlDispatcher = class {
362734
363195
  this,
362735
363196
  "PermissionController"
362736
363197
  );
363198
+ this.sdkMcpController = new SdkMcpController(
363199
+ context2,
363200
+ this,
363201
+ "SdkMcpController"
363202
+ );
362737
363203
  this.context.abortSignal.addEventListener("abort", () => {
362738
363204
  this.shutdown();
362739
363205
  });
@@ -362839,6 +363305,7 @@ var ControlDispatcher = class {
362839
363305
  this.pendingOutgoingRequests.clear();
362840
363306
  this.systemController.cleanup();
362841
363307
  this.permissionController.cleanup();
363308
+ this.sdkMcpController.cleanup();
362842
363309
  }
362843
363310
  /**
362844
363311
  * Registers an incoming request in the pending registry
@@ -362881,6 +363348,40 @@ var ControlDispatcher = class {
362881
363348
  this.pendingOutgoingRequests.delete(requestId);
362882
363349
  }
362883
363350
  }
363351
+ /**
363352
+ * Get count of pending incoming requests (for debugging)
363353
+ */
363354
+ getPendingIncomingRequestCount() {
363355
+ return this.pendingIncomingRequests.size;
363356
+ }
363357
+ /**
363358
+ * Wait for all incoming request handlers to complete.
363359
+ *
363360
+ * Uses polling since we don't have direct Promise references to handlers.
363361
+ * The pendingIncomingRequests map is managed by BaseController:
363362
+ * - Registered when handler starts (in handleRequest)
363363
+ * - Deregistered when handler completes (success or error)
363364
+ *
363365
+ * @param pollIntervalMs - How often to check (default 50ms)
363366
+ * @param timeoutMs - Maximum wait time (default 30s)
363367
+ */
363368
+ async waitForPendingIncomingRequests(pollIntervalMs = 50, timeoutMs = 3e4) {
363369
+ const startTime = Date.now();
363370
+ while (this.pendingIncomingRequests.size > 0) {
363371
+ if (Date.now() - startTime > timeoutMs) {
363372
+ if (this.context.debugMode) {
363373
+ console.error(
363374
+ `[ControlDispatcher] Timeout waiting for ${this.pendingIncomingRequests.size} pending incoming requests`
363375
+ );
363376
+ }
363377
+ break;
363378
+ }
363379
+ await new Promise((resolve26) => setTimeout(resolve26, pollIntervalMs));
363380
+ }
363381
+ if (this.context.debugMode && this.pendingIncomingRequests.size === 0) {
363382
+ console.error("[ControlDispatcher] All incoming requests completed");
363383
+ }
363384
+ }
362884
363385
  /**
362885
363386
  * Returns the controller that handles the given request subtype
362886
363387
  */
@@ -362894,9 +363395,8 @@ var ControlDispatcher = class {
362894
363395
  case "can_use_tool":
362895
363396
  case "set_permission_mode":
362896
363397
  return this.permissionController;
362897
- // case 'mcp_message':
362898
- // case 'mcp_server_status':
362899
- // return this.mcpController;
363398
+ case "mcp_server_status":
363399
+ return this.sdkMcpController;
362900
363400
  // case 'hook_callback':
362901
363401
  // return this.hookController;
362902
363402
  default:
@@ -363175,6 +363675,11 @@ var Session2 = class {
363175
363675
  processingPromise = null;
363176
363676
  isShuttingDown = false;
363177
363677
  configInitialized = false;
363678
+ // Single initialization promise that resolves when session is ready for user messages.
363679
+ // Created lazily once initialization actually starts.
363680
+ initializationPromise = null;
363681
+ initializationResolve = null;
363682
+ initializationReject = null;
363178
363683
  constructor(config2, initialPrompt) {
363179
363684
  this.config = config2;
363180
363685
  this.sessionId = config2.getSessionId();
@@ -363188,11 +363693,28 @@ var Session2 = class {
363188
363693
  );
363189
363694
  this.setupSignalHandlers();
363190
363695
  }
363696
+ ensureInitializationPromise() {
363697
+ if (this.initializationPromise) {
363698
+ return;
363699
+ }
363700
+ this.initializationPromise = new Promise((resolve26, reject) => {
363701
+ this.initializationResolve = () => {
363702
+ resolve26();
363703
+ this.initializationResolve = null;
363704
+ this.initializationReject = null;
363705
+ };
363706
+ this.initializationReject = (error2) => {
363707
+ reject(error2);
363708
+ this.initializationResolve = null;
363709
+ this.initializationReject = null;
363710
+ };
363711
+ });
363712
+ }
363191
363713
  getNextPromptId() {
363192
363714
  this.promptIdCounter++;
363193
363715
  return `${this.sessionId}########${this.promptIdCounter}`;
363194
363716
  }
363195
- async ensureConfigInitialized() {
363717
+ async ensureConfigInitialized(options2) {
363196
363718
  if (this.configInitialized) {
363197
363719
  return;
363198
363720
  }
@@ -363200,7 +363722,7 @@ var Session2 = class {
363200
363722
  console.error("[Session] Initializing config");
363201
363723
  }
363202
363724
  try {
363203
- await this.config.initialize();
363725
+ await this.config.initialize(options2);
363204
363726
  this.configInitialized = true;
363205
363727
  } catch (error2) {
363206
363728
  if (this.debugMode) {
@@ -363209,6 +363731,41 @@ var Session2 = class {
363209
363731
  throw error2;
363210
363732
  }
363211
363733
  }
363734
+ /**
363735
+ * Mark initialization as complete
363736
+ */
363737
+ completeInitialization() {
363738
+ if (this.initializationResolve) {
363739
+ if (this.debugMode) {
363740
+ console.error("[Session] Initialization complete");
363741
+ }
363742
+ this.initializationResolve();
363743
+ this.initializationResolve = null;
363744
+ this.initializationReject = null;
363745
+ }
363746
+ }
363747
+ /**
363748
+ * Mark initialization as failed
363749
+ */
363750
+ failInitialization(error2) {
363751
+ if (this.initializationReject) {
363752
+ if (this.debugMode) {
363753
+ console.error("[Session] Initialization failed:", error2);
363754
+ }
363755
+ this.initializationReject(error2);
363756
+ this.initializationResolve = null;
363757
+ this.initializationReject = null;
363758
+ }
363759
+ }
363760
+ /**
363761
+ * Wait for session to be ready for user messages
363762
+ */
363763
+ async waitForInitialization() {
363764
+ if (!this.initializationPromise) {
363765
+ return;
363766
+ }
363767
+ await this.initializationPromise;
363768
+ }
363212
363769
  ensureControlSystem() {
363213
363770
  if (this.controlContext && this.dispatcher && this.controlService) {
363214
363771
  return;
@@ -363236,33 +363793,81 @@ var Session2 = class {
363236
363793
  }
363237
363794
  return this.dispatcher;
363238
363795
  }
363239
- async handleFirstMessage(message) {
363796
+ /**
363797
+ * Handle the first message to determine session mode (SDK vs direct).
363798
+ * This is synchronous from the message loop's perspective - it starts
363799
+ * async work but does not return a promise that the loop awaits.
363800
+ *
363801
+ * The initialization completes asynchronously and resolves initializationPromise
363802
+ * when ready for user messages.
363803
+ */
363804
+ handleFirstMessage(message) {
363240
363805
  if (isControlRequest(message)) {
363241
363806
  const request4 = message;
363242
363807
  this.controlSystemEnabled = true;
363243
363808
  this.ensureControlSystem();
363244
363809
  if (request4.request.subtype === "initialize") {
363245
- await this.dispatcher?.dispatch(request4);
363246
- await this.ensureConfigInitialized();
363247
- return true;
363810
+ void this.initializeSdkMode(request4);
363811
+ return;
363248
363812
  }
363249
363813
  if (this.debugMode) {
363250
363814
  console.error(
363251
363815
  "[Session] Ignoring non-initialize control request during initialization"
363252
363816
  );
363253
363817
  }
363254
- return true;
363818
+ return;
363255
363819
  }
363256
363820
  if (isCLIUserMessage(message)) {
363257
363821
  this.controlSystemEnabled = false;
363258
- await this.ensureConfigInitialized();
363259
- this.enqueueUserMessage(message);
363260
- return true;
363822
+ void this.initializeDirectMode(message);
363823
+ return;
363261
363824
  }
363262
363825
  this.controlSystemEnabled = false;
363263
- return false;
363264
363826
  }
363265
- async handleControlRequest(request4) {
363827
+ /**
363828
+ * SDK mode initialization flow
363829
+ * Dispatches initialize request and initializes config with MCP support
363830
+ */
363831
+ async initializeSdkMode(request4) {
363832
+ this.ensureInitializationPromise();
363833
+ try {
363834
+ await this.dispatcher?.dispatch(request4);
363835
+ const sendSdkMcpMessage = this.dispatcher?.sdkMcpController.createSendSdkMcpMessage();
363836
+ await this.ensureConfigInitialized({ sendSdkMcpMessage });
363837
+ this.completeInitialization();
363838
+ } catch (error2) {
363839
+ if (this.debugMode) {
363840
+ console.error("[Session] SDK mode initialization failed:", error2);
363841
+ }
363842
+ this.failInitialization(
363843
+ error2 instanceof Error ? error2 : new Error(String(error2))
363844
+ );
363845
+ }
363846
+ }
363847
+ /**
363848
+ * Direct mode initialization flow
363849
+ * Initializes config and enqueues the first user message
363850
+ */
363851
+ async initializeDirectMode(userMessage) {
363852
+ this.ensureInitializationPromise();
363853
+ try {
363854
+ await this.ensureConfigInitialized();
363855
+ this.completeInitialization();
363856
+ this.enqueueUserMessage(userMessage);
363857
+ } catch (error2) {
363858
+ if (this.debugMode) {
363859
+ console.error("[Session] Direct mode initialization failed:", error2);
363860
+ }
363861
+ this.failInitialization(
363862
+ error2 instanceof Error ? error2 : new Error(String(error2))
363863
+ );
363864
+ }
363865
+ }
363866
+ /**
363867
+ * Handle control request asynchronously (fire-and-forget from main loop).
363868
+ * Errors are handled internally and responses sent by dispatcher.
363869
+ */
363870
+ handleControlRequestAsync(request4) {
363266
363871
  const dispatcher = this.getDispatcher();
363267
363872
  if (!dispatcher) {
363268
363873
  if (this.debugMode) {
@@ -363270,8 +363875,16 @@ var Session2 = class {
363270
363875
  }
363271
363876
  return;
363272
363877
  }
363273
- await dispatcher.dispatch(request4);
363878
+ void dispatcher.dispatch(request4).catch((error2) => {
363879
+ if (this.debugMode) {
363880
+ console.error("[Session] Control request dispatch error:", error2);
363881
+ }
363882
+ });
363274
363883
  }
363884
+ /**
363885
+ * Handle control response - MUST be synchronous
363886
+ * This resolves pending outgoing requests, breaking the deadlock cycle.
363887
+ */
363275
363888
  handleControlResponse(response) {
363276
363889
  const dispatcher = this.getDispatcher();
363277
363890
  if (!dispatcher) {
@@ -363294,7 +363907,7 @@ var Session2 = class {
363294
363907
  }
363295
363908
  return;
363296
363909
  }
363297
- await this.ensureConfigInitialized();
363910
+ await this.waitForInitialization();
363298
363911
  const promptId = this.getNextPromptId();
363299
363912
  try {
363300
363913
  await runNonInteractive(
@@ -363374,23 +363987,45 @@ var Session2 = class {
363374
363987
  process.on("SIGINT", this.shutdownHandler);
363375
363988
  process.on("SIGTERM", this.shutdownHandler);
363376
363989
  }
363377
- async shutdown() {
363378
- if (this.debugMode) {
363379
- console.error("[Session] Shutting down");
363990
+ /**
363991
+ * Wait for all pending work to complete before shutdown
363992
+ */
363993
+ async waitForAllPendingWork() {
363994
+ try {
363995
+ await this.waitForInitialization();
363996
+ } catch (error2) {
363997
+ if (this.debugMode) {
363998
+ console.error("[Session] Initialization error during shutdown:", error2);
363999
+ }
363380
364000
  }
363381
- this.isShuttingDown = true;
363382
- if (this.processingPromise) {
364001
+ if (this.dispatcher) {
364002
+ const pendingCount = this.dispatcher.getPendingIncomingRequestCount();
364003
+ if (pendingCount > 0 && this.debugMode) {
364004
+ console.error(
364005
+ `[Session] Waiting for ${pendingCount} pending control request handlers`
364006
+ );
364007
+ }
364008
+ await this.dispatcher.waitForPendingIncomingRequests();
364009
+ }
364010
+ while (this.processingPromise) {
364011
+ if (this.debugMode) {
364012
+ console.error("[Session] Waiting for user message processing");
364013
+ }
363383
364014
  try {
363384
364015
  await this.processingPromise;
363385
364016
  } catch (error2) {
363386
364017
  if (this.debugMode) {
363387
- console.error(
363388
- "[Session] Error waiting for processing to complete:",
363389
- error2
363390
- );
364018
+ console.error("[Session] Error in user message processing:", error2);
363391
364019
  }
363392
364020
  }
363393
364021
  }
364022
+ }
364023
+ async shutdown() {
364024
+ if (this.debugMode) {
364025
+ console.error("[Session] Shutting down");
364026
+ }
364027
+ this.isShuttingDown = true;
364028
+ await this.waitForAllPendingWork();
363394
364029
  this.dispatcher?.shutdown();
363395
364030
  this.cleanupSignalHandlers();
363396
364031
  }
@@ -363401,36 +364036,44 @@ var Session2 = class {
363401
364036
  this.shutdownHandler = null;
363402
364037
  }
363403
364038
  }
364039
+ /**
364040
+ * Main message processing loop
364041
+ *
364042
+ * CRITICAL: This loop must NEVER await handlers that might need to
364043
+ * send control requests and wait for responses. Such handlers must
364044
+ * be started in fire-and-forget mode, allowing the loop to continue
364045
+ * reading responses that resolve pending requests.
364046
+ *
364047
+ * Message handling order:
364048
+ * 1. control_response - FIRST, synchronously resolves pending requests
364049
+ * 2. First message - determines mode, starts async initialization
364050
+ * 3. control_request - fire-and-forget, tracked by dispatcher
364051
+ * 4. control_cancel - synchronous
364052
+ * 5. user_message - enqueued for processing
364053
+ */
363404
364054
  async run() {
363405
364055
  try {
363406
364056
  if (this.debugMode) {
363407
364057
  console.error("[Session] Starting session", this.sessionId);
363408
364058
  }
363409
364059
  if (this.initialPrompt !== null) {
363410
- const handled = await this.handleFirstMessage(this.initialPrompt);
363411
- if (handled && this.isShuttingDown) {
363412
- await this.shutdown();
363413
- return;
363414
- }
364060
+ this.handleFirstMessage(this.initialPrompt);
363415
364061
  }
363416
364062
  try {
363417
364063
  for await (const message of this.inputReader.read()) {
363418
364064
  if (this.abortController.signal.aborted) {
363419
364065
  break;
363420
364066
  }
364067
+ if (isControlResponse(message)) {
364068
+ this.handleControlResponse(message);
364069
+ continue;
364070
+ }
363421
364071
  if (this.controlSystemEnabled === null) {
363422
- const handled = await this.handleFirstMessage(message);
363423
- if (handled) {
363424
- if (this.isShuttingDown) {
363425
- break;
363426
- }
363427
- continue;
363428
- }
364072
+ this.handleFirstMessage(message);
364073
+ continue;
363429
364074
  }
363430
364075
  if (isControlRequest(message)) {
363431
- await this.handleControlRequest(message);
363432
- } else if (isControlResponse(message)) {
363433
- this.handleControlResponse(message);
364076
+ this.handleControlRequestAsync(message);
363434
364077
  } else if (isControlCancel(message)) {
363435
364078
  this.handleControlCancel(message);
363436
364079
  } else if (isCLIUserMessage(message)) {
@@ -363453,18 +364096,7 @@ var Session2 = class {
363453
364096
  }
363454
364097
  throw streamError;
363455
364098
  }
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
- }
364099
+ await this.waitForAllPendingWork();
363468
364100
  await this.shutdown();
363469
364101
  } catch (error2) {
363470
364102
  if (this.debugMode) {
@@ -407874,7 +408506,7 @@ var GeminiAgent = class {
407874
408506
  name: APPROVAL_MODE_INFO[mode].name,
407875
408507
  description: APPROVAL_MODE_INFO[mode].description
407876
408508
  }));
407877
- const version3 = "0.1.3-alpha.6";
408509
+ const version3 = "0.1.3";
407878
408510
  return {
407879
408511
  protocolVersion: PROTOCOL_VERSION,
407880
408512
  agentInfo: {
@@ -408214,8 +408846,9 @@ async function main() {
408214
408846
  process.exit(1);
408215
408847
  }
408216
408848
  }
408849
+ const inputFormat = argv.inputFormat;
408217
408850
  let stdinData = "";
408218
- if (!process.stdin.isTTY) {
408851
+ if (!process.stdin.isTTY && inputFormat !== "stream-json") {
408219
408852
  stdinData = await readStdin();
408220
408853
  }
408221
408854
  const injectStdinIntoArgs = /* @__PURE__ */ __name((args, stdinData2) => {
@@ -408471,12 +409104,12 @@ main().catch((error2) => {
408471
409104
  */
408472
409105
  /**
408473
409106
  * @license
408474
- * Copyright 2025 RDMind
409107
+ * Copyright 2025 Qwen Team
408475
409108
  * SPDX-License-Identifier: Apache-2.0
408476
409109
  */
408477
409110
  /**
408478
409111
  * @license
408479
- * Copyright 2025 Qwen Team
409112
+ * Copyright 2025 RDMind
408480
409113
  * SPDX-License-Identifier: Apache-2.0
408481
409114
  */
408482
409115
  /*! Bundled license information: