@ketd/gemini-cli-sdk 0.3.5 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -506,7 +506,7 @@ interface UserInputMessage {
506
506
  /**
507
507
  * Control subtypes for control messages
508
508
  */
509
- type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history' | 'resume_session';
509
+ type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history' | 'resume_session' | 'replace_history';
510
510
  /**
511
511
  * Interrupt control - stop current processing
512
512
  */
@@ -514,13 +514,21 @@ interface InterruptControl {
514
514
  subtype: 'interrupt' | 'cancel' | 'shutdown';
515
515
  }
516
516
  /**
517
- * Truncate history control - remove messages from a specific index
517
+ * Truncate history control - remove messages from a specific index or by user turn count
518
518
  * Used for edit/retry functionality
519
+ *
520
+ * Two modes:
521
+ * - keepUserTurns: Semantic mode — keep N complete user turns (handles tool call Content items correctly)
522
+ * - fromIndex: Raw mode — truncate from a specific Content[] index (legacy, doesn't account for tool calls)
523
+ *
524
+ * When both are provided, keepUserTurns takes precedence.
519
525
  */
520
526
  interface TruncateHistoryControl {
521
527
  subtype: 'truncate_history';
522
- /** Index from which to truncate (0-based, inclusive) */
523
- fromIndex: number;
528
+ /** Index from which to truncate (0-based, inclusive). Used when keepUserTurns is not set. */
529
+ fromIndex?: number;
530
+ /** Number of complete user turns to keep. The CLI scans its history to find the correct Content[] split point. */
531
+ keepUserTurns?: number;
524
532
  }
525
533
  /**
526
534
  * Resume session control - load history from a session file
@@ -531,12 +539,24 @@ interface ResumeSessionControl {
531
539
  /** Path to the session file to resume from */
532
540
  sessionFilePath: string;
533
541
  }
542
+ /**
543
+ * Replace history control - fully replace CLI in-memory history
544
+ * Used when messages are deleted from DB and CLI history needs to be rebuilt
545
+ */
546
+ interface ReplaceHistoryControl {
547
+ subtype: 'replace_history';
548
+ /** Full replacement history as Gemini Content[] format */
549
+ contents: Array<{
550
+ role: string;
551
+ parts: unknown[];
552
+ }>;
553
+ }
534
554
  /**
535
555
  * Control message sent to CLI
536
556
  */
537
557
  interface ControlInputMessage {
538
558
  type: JsonInputMessageType.CONTROL;
539
- control: InterruptControl | TruncateHistoryControl | ResumeSessionControl;
559
+ control: InterruptControl | TruncateHistoryControl | ResumeSessionControl | ReplaceHistoryControl;
540
560
  session_id?: string;
541
561
  }
542
562
  /**
@@ -583,9 +603,16 @@ interface MCPServerConfig {
583
603
  cwd?: string;
584
604
  /** Environment variables */
585
605
  env?: Record<string, string>;
586
- /** URL for SSE transport */
606
+ /**
607
+ * Transport type for URL-based connections
608
+ * - 'http': Streamable HTTP transport (recommended for mcp-chrome)
609
+ * - 'sse': Server-Sent Events transport
610
+ * When not specified with url, defaults to 'http'
611
+ */
612
+ type?: 'http' | 'sse';
613
+ /** URL for the MCP server (used with type field) */
587
614
  url?: string;
588
- /** URL for HTTP streaming transport */
615
+ /** URL for HTTP streaming transport (deprecated, use url with type: 'http') */
589
616
  httpUrl?: string;
590
617
  /** Custom headers for HTTP transports */
591
618
  headers?: Record<string, string>;
@@ -602,6 +629,38 @@ interface MCPServerConfig {
602
629
  * MCP Servers configuration map
603
630
  */
604
631
  type MCPServersConfig = Record<string, MCPServerConfig>;
632
+ /**
633
+ * Tools configuration for Gemini CLI settings.json
634
+ * Used to configure custom tool discovery and execution commands
635
+ */
636
+ interface ToolsConfig {
637
+ /**
638
+ * Command to discover available tools
639
+ * @example '"node" "/path/to/discover-tools.cjs"'
640
+ */
641
+ discoveryCommand?: string;
642
+ /**
643
+ * Command to call/execute a tool
644
+ * @example '"node" "/path/to/call-tool.cjs"'
645
+ */
646
+ callCommand?: string;
647
+ /**
648
+ * Enable hooks for tool execution
649
+ * Set to true when using hooks configuration
650
+ */
651
+ enableHooks?: boolean;
652
+ }
653
+ /**
654
+ * Context configuration for Gemini CLI settings.json
655
+ * Used to configure context file settings
656
+ */
657
+ interface ContextConfig {
658
+ /**
659
+ * Name of the context file (e.g., 'AOE.md')
660
+ * Gemini CLI will look for this file in the working directory
661
+ */
662
+ fileName?: string;
663
+ }
605
664
  /**
606
665
  * Options for GeminiStreamClient
607
666
  */
@@ -694,12 +753,6 @@ interface GeminiStreamOptions {
694
753
  * ```
695
754
  */
696
755
  mcpServers?: MCPServersConfig;
697
- /**
698
- * Resume from a previous session file path
699
- * If provided, Gemini CLI will load the session history using --resume flag
700
- * @example '/path/to/session-2025-01-01T12-00-abc123.json'
701
- */
702
- resumeSessionFilePath?: string;
703
756
  /**
704
757
  * Custom logger implementation
705
758
  * If not provided, uses console with [GeminiStreamClient] prefix
@@ -715,6 +768,34 @@ interface GeminiStreamOptions {
715
768
  * ```
716
769
  */
717
770
  logger?: Logger;
771
+ /**
772
+ * Tools configuration for Gemini CLI
773
+ * Configures custom tool discovery and execution commands
774
+ * Written to settings.json tools field
775
+ *
776
+ * @example
777
+ * ```typescript
778
+ * tools: {
779
+ * discoveryCommand: '"node" "/path/to/discover-tools.cjs"',
780
+ * callCommand: '"node" "/path/to/call-tool.cjs"',
781
+ * enableHooks: true,
782
+ * }
783
+ * ```
784
+ */
785
+ tools?: ToolsConfig;
786
+ /**
787
+ * Context configuration for Gemini CLI
788
+ * Configures context file settings
789
+ * Written to settings.json context field
790
+ *
791
+ * @example
792
+ * ```typescript
793
+ * context: {
794
+ * fileName: 'AOE.md',
795
+ * }
796
+ * ```
797
+ */
798
+ context?: ContextConfig;
718
799
  }
719
800
 
720
801
  /**
@@ -904,9 +985,13 @@ declare class GeminiStreamClient extends EventEmitter$1 {
904
985
  *
905
986
  * Used for edit/retry functionality where subsequent messages need to be discarded.
906
987
  *
907
- * @param fromIndex - Index from which to truncate (0-based, inclusive)
988
+ * @param options - Truncation options: either keepUserTurns (preferred) or fromIndex (legacy)
908
989
  */
909
- truncateHistory(fromIndex: number): Promise<void>;
990
+ truncateHistory(options: number | {
991
+ keepUserTurns: number;
992
+ } | {
993
+ fromIndex: number;
994
+ }): Promise<void>;
910
995
  /**
911
996
  * Resume session from a session file
912
997
  *
@@ -919,6 +1004,21 @@ declare class GeminiStreamClient extends EventEmitter$1 {
919
1004
  * @param sessionFilePath - Path to the session file to resume from
920
1005
  */
921
1006
  resumeSession(sessionFilePath: string): Promise<void>;
1007
+ /**
1008
+ * Replace CLI in-memory history with provided contents
1009
+ *
1010
+ * This sends a control message to the CLI to:
1011
+ * 1. Replace the entire in-memory history with the provided contents
1012
+ * 2. Clear session.json (DB is the source of truth)
1013
+ *
1014
+ * Used when messages are deleted from DB and CLI history needs to be rebuilt.
1015
+ *
1016
+ * @param contents - Full replacement history in Gemini Content[] format
1017
+ */
1018
+ replaceHistory(contents: Array<{
1019
+ role: string;
1020
+ parts: unknown[];
1021
+ }>): Promise<void>;
922
1022
  /**
923
1023
  * Stop the CLI process
924
1024
  */
@@ -945,6 +1045,9 @@ declare class GeminiStreamClient extends EventEmitter$1 {
945
1045
  * Note: Gemini CLI does not support --settings-file parameter.
946
1046
  * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
947
1047
  * where GEMINI_CONFIG_DIR is set via environment variable.
1048
+ *
1049
+ * This method merges with existing settings.json if present, preserving
1050
+ * any configuration written by the host application (e.g., tools.discoveryCommand).
948
1051
  */
949
1052
  private createTempSettings;
950
1053
  /**
@@ -1034,4 +1137,4 @@ declare function formatDuration(ms: number): string;
1034
1137
  */
1035
1138
  declare function formatTokens(tokens: number): string;
1036
1139
 
1037
- export { type ControlInputMessage, type ControlSubtype, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type HooksConfiguration, type InitEvent, type InterruptControl, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, LogLevel, type Logger, type LoggerOptions, type MCPServerConfig, type MCPServersConfig, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type ResumeSessionControl, SDKLogger, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type TruncateHistoryControl, type UserInputMessage, createLogger, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, sdkLogger, silentLogger, validateApiKey, validateModel };
1140
+ export { type ContextConfig, type ControlInputMessage, type ControlSubtype, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type HooksConfiguration, type InitEvent, type InterruptControl, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, LogLevel, type Logger, type LoggerOptions, type MCPServerConfig, type MCPServersConfig, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type ResumeSessionControl, SDKLogger, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type ToolsConfig, type TruncateHistoryControl, type UserInputMessage, createLogger, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, sdkLogger, silentLogger, validateApiKey, validateModel };
package/dist/index.d.ts CHANGED
@@ -506,7 +506,7 @@ interface UserInputMessage {
506
506
  /**
507
507
  * Control subtypes for control messages
508
508
  */
509
- type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history' | 'resume_session';
509
+ type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history' | 'resume_session' | 'replace_history';
510
510
  /**
511
511
  * Interrupt control - stop current processing
512
512
  */
@@ -514,13 +514,21 @@ interface InterruptControl {
514
514
  subtype: 'interrupt' | 'cancel' | 'shutdown';
515
515
  }
516
516
  /**
517
- * Truncate history control - remove messages from a specific index
517
+ * Truncate history control - remove messages from a specific index or by user turn count
518
518
  * Used for edit/retry functionality
519
+ *
520
+ * Two modes:
521
+ * - keepUserTurns: Semantic mode — keep N complete user turns (handles tool call Content items correctly)
522
+ * - fromIndex: Raw mode — truncate from a specific Content[] index (legacy, doesn't account for tool calls)
523
+ *
524
+ * When both are provided, keepUserTurns takes precedence.
519
525
  */
520
526
  interface TruncateHistoryControl {
521
527
  subtype: 'truncate_history';
522
- /** Index from which to truncate (0-based, inclusive) */
523
- fromIndex: number;
528
+ /** Index from which to truncate (0-based, inclusive). Used when keepUserTurns is not set. */
529
+ fromIndex?: number;
530
+ /** Number of complete user turns to keep. The CLI scans its history to find the correct Content[] split point. */
531
+ keepUserTurns?: number;
524
532
  }
525
533
  /**
526
534
  * Resume session control - load history from a session file
@@ -531,12 +539,24 @@ interface ResumeSessionControl {
531
539
  /** Path to the session file to resume from */
532
540
  sessionFilePath: string;
533
541
  }
542
+ /**
543
+ * Replace history control - fully replace CLI in-memory history
544
+ * Used when messages are deleted from DB and CLI history needs to be rebuilt
545
+ */
546
+ interface ReplaceHistoryControl {
547
+ subtype: 'replace_history';
548
+ /** Full replacement history as Gemini Content[] format */
549
+ contents: Array<{
550
+ role: string;
551
+ parts: unknown[];
552
+ }>;
553
+ }
534
554
  /**
535
555
  * Control message sent to CLI
536
556
  */
537
557
  interface ControlInputMessage {
538
558
  type: JsonInputMessageType.CONTROL;
539
- control: InterruptControl | TruncateHistoryControl | ResumeSessionControl;
559
+ control: InterruptControl | TruncateHistoryControl | ResumeSessionControl | ReplaceHistoryControl;
540
560
  session_id?: string;
541
561
  }
542
562
  /**
@@ -583,9 +603,16 @@ interface MCPServerConfig {
583
603
  cwd?: string;
584
604
  /** Environment variables */
585
605
  env?: Record<string, string>;
586
- /** URL for SSE transport */
606
+ /**
607
+ * Transport type for URL-based connections
608
+ * - 'http': Streamable HTTP transport (recommended for mcp-chrome)
609
+ * - 'sse': Server-Sent Events transport
610
+ * When not specified with url, defaults to 'http'
611
+ */
612
+ type?: 'http' | 'sse';
613
+ /** URL for the MCP server (used with type field) */
587
614
  url?: string;
588
- /** URL for HTTP streaming transport */
615
+ /** URL for HTTP streaming transport (deprecated, use url with type: 'http') */
589
616
  httpUrl?: string;
590
617
  /** Custom headers for HTTP transports */
591
618
  headers?: Record<string, string>;
@@ -602,6 +629,38 @@ interface MCPServerConfig {
602
629
  * MCP Servers configuration map
603
630
  */
604
631
  type MCPServersConfig = Record<string, MCPServerConfig>;
632
+ /**
633
+ * Tools configuration for Gemini CLI settings.json
634
+ * Used to configure custom tool discovery and execution commands
635
+ */
636
+ interface ToolsConfig {
637
+ /**
638
+ * Command to discover available tools
639
+ * @example '"node" "/path/to/discover-tools.cjs"'
640
+ */
641
+ discoveryCommand?: string;
642
+ /**
643
+ * Command to call/execute a tool
644
+ * @example '"node" "/path/to/call-tool.cjs"'
645
+ */
646
+ callCommand?: string;
647
+ /**
648
+ * Enable hooks for tool execution
649
+ * Set to true when using hooks configuration
650
+ */
651
+ enableHooks?: boolean;
652
+ }
653
+ /**
654
+ * Context configuration for Gemini CLI settings.json
655
+ * Used to configure context file settings
656
+ */
657
+ interface ContextConfig {
658
+ /**
659
+ * Name of the context file (e.g., 'AOE.md')
660
+ * Gemini CLI will look for this file in the working directory
661
+ */
662
+ fileName?: string;
663
+ }
605
664
  /**
606
665
  * Options for GeminiStreamClient
607
666
  */
@@ -694,12 +753,6 @@ interface GeminiStreamOptions {
694
753
  * ```
695
754
  */
696
755
  mcpServers?: MCPServersConfig;
697
- /**
698
- * Resume from a previous session file path
699
- * If provided, Gemini CLI will load the session history using --resume flag
700
- * @example '/path/to/session-2025-01-01T12-00-abc123.json'
701
- */
702
- resumeSessionFilePath?: string;
703
756
  /**
704
757
  * Custom logger implementation
705
758
  * If not provided, uses console with [GeminiStreamClient] prefix
@@ -715,6 +768,34 @@ interface GeminiStreamOptions {
715
768
  * ```
716
769
  */
717
770
  logger?: Logger;
771
+ /**
772
+ * Tools configuration for Gemini CLI
773
+ * Configures custom tool discovery and execution commands
774
+ * Written to settings.json tools field
775
+ *
776
+ * @example
777
+ * ```typescript
778
+ * tools: {
779
+ * discoveryCommand: '"node" "/path/to/discover-tools.cjs"',
780
+ * callCommand: '"node" "/path/to/call-tool.cjs"',
781
+ * enableHooks: true,
782
+ * }
783
+ * ```
784
+ */
785
+ tools?: ToolsConfig;
786
+ /**
787
+ * Context configuration for Gemini CLI
788
+ * Configures context file settings
789
+ * Written to settings.json context field
790
+ *
791
+ * @example
792
+ * ```typescript
793
+ * context: {
794
+ * fileName: 'AOE.md',
795
+ * }
796
+ * ```
797
+ */
798
+ context?: ContextConfig;
718
799
  }
719
800
 
720
801
  /**
@@ -904,9 +985,13 @@ declare class GeminiStreamClient extends EventEmitter$1 {
904
985
  *
905
986
  * Used for edit/retry functionality where subsequent messages need to be discarded.
906
987
  *
907
- * @param fromIndex - Index from which to truncate (0-based, inclusive)
988
+ * @param options - Truncation options: either keepUserTurns (preferred) or fromIndex (legacy)
908
989
  */
909
- truncateHistory(fromIndex: number): Promise<void>;
990
+ truncateHistory(options: number | {
991
+ keepUserTurns: number;
992
+ } | {
993
+ fromIndex: number;
994
+ }): Promise<void>;
910
995
  /**
911
996
  * Resume session from a session file
912
997
  *
@@ -919,6 +1004,21 @@ declare class GeminiStreamClient extends EventEmitter$1 {
919
1004
  * @param sessionFilePath - Path to the session file to resume from
920
1005
  */
921
1006
  resumeSession(sessionFilePath: string): Promise<void>;
1007
+ /**
1008
+ * Replace CLI in-memory history with provided contents
1009
+ *
1010
+ * This sends a control message to the CLI to:
1011
+ * 1. Replace the entire in-memory history with the provided contents
1012
+ * 2. Clear session.json (DB is the source of truth)
1013
+ *
1014
+ * Used when messages are deleted from DB and CLI history needs to be rebuilt.
1015
+ *
1016
+ * @param contents - Full replacement history in Gemini Content[] format
1017
+ */
1018
+ replaceHistory(contents: Array<{
1019
+ role: string;
1020
+ parts: unknown[];
1021
+ }>): Promise<void>;
922
1022
  /**
923
1023
  * Stop the CLI process
924
1024
  */
@@ -945,6 +1045,9 @@ declare class GeminiStreamClient extends EventEmitter$1 {
945
1045
  * Note: Gemini CLI does not support --settings-file parameter.
946
1046
  * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
947
1047
  * where GEMINI_CONFIG_DIR is set via environment variable.
1048
+ *
1049
+ * This method merges with existing settings.json if present, preserving
1050
+ * any configuration written by the host application (e.g., tools.discoveryCommand).
948
1051
  */
949
1052
  private createTempSettings;
950
1053
  /**
@@ -1034,4 +1137,4 @@ declare function formatDuration(ms: number): string;
1034
1137
  */
1035
1138
  declare function formatTokens(tokens: number): string;
1036
1139
 
1037
- export { type ControlInputMessage, type ControlSubtype, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type HooksConfiguration, type InitEvent, type InterruptControl, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, LogLevel, type Logger, type LoggerOptions, type MCPServerConfig, type MCPServersConfig, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type ResumeSessionControl, SDKLogger, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type TruncateHistoryControl, type UserInputMessage, createLogger, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, sdkLogger, silentLogger, validateApiKey, validateModel };
1140
+ export { type ContextConfig, type ControlInputMessage, type ControlSubtype, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type HooksConfiguration, type InitEvent, type InterruptControl, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, LogLevel, type Logger, type LoggerOptions, type MCPServerConfig, type MCPServersConfig, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type ResumeSessionControl, SDKLogger, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type ToolsConfig, type TruncateHistoryControl, type UserInputMessage, createLogger, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, sdkLogger, silentLogger, validateApiKey, validateModel };
package/dist/index.js CHANGED
@@ -492,7 +492,7 @@ var GeminiStreamClient = class extends EventEmitter {
492
492
  throw new GeminiSDKError("Process already started");
493
493
  }
494
494
  this.status = "running" /* RUNNING */;
495
- if (this.options.hooks || this.options.mcpServers) {
495
+ if (this.options.hooks || this.options.mcpServers || this.options.tools || this.options.context) {
496
496
  await this.createTempSettings();
497
497
  }
498
498
  const args = this.buildCommand();
@@ -579,21 +579,32 @@ var GeminiStreamClient = class extends EventEmitter {
579
579
  *
580
580
  * Used for edit/retry functionality where subsequent messages need to be discarded.
581
581
  *
582
- * @param fromIndex - Index from which to truncate (0-based, inclusive)
582
+ * @param options - Truncation options: either keepUserTurns (preferred) or fromIndex (legacy)
583
583
  */
584
- async truncateHistory(fromIndex) {
584
+ async truncateHistory(options) {
585
585
  if (!this.isReady()) {
586
586
  throw new GeminiSDKError("Client not ready. Call start() first.");
587
587
  }
588
- if (fromIndex < 0) {
589
- throw new GeminiSDKError("fromIndex must be non-negative");
588
+ let control;
589
+ if (typeof options === "number") {
590
+ if (options < 0) {
591
+ throw new GeminiSDKError("fromIndex must be non-negative");
592
+ }
593
+ control = { subtype: "truncate_history", fromIndex: options };
594
+ } else if ("keepUserTurns" in options) {
595
+ if (options.keepUserTurns < 0) {
596
+ throw new GeminiSDKError("keepUserTurns must be non-negative");
597
+ }
598
+ control = { subtype: "truncate_history", keepUserTurns: options.keepUserTurns };
599
+ } else {
600
+ if (options.fromIndex < 0) {
601
+ throw new GeminiSDKError("fromIndex must be non-negative");
602
+ }
603
+ control = { subtype: "truncate_history", fromIndex: options.fromIndex };
590
604
  }
591
605
  const message = {
592
606
  type: "control" /* CONTROL */,
593
- control: {
594
- subtype: "truncate_history",
595
- fromIndex
596
- },
607
+ control,
597
608
  session_id: this.options.sessionId
598
609
  };
599
610
  this.writeMessage(message);
@@ -626,6 +637,31 @@ var GeminiStreamClient = class extends EventEmitter {
626
637
  };
627
638
  this.writeMessage(message);
628
639
  }
640
+ /**
641
+ * Replace CLI in-memory history with provided contents
642
+ *
643
+ * This sends a control message to the CLI to:
644
+ * 1. Replace the entire in-memory history with the provided contents
645
+ * 2. Clear session.json (DB is the source of truth)
646
+ *
647
+ * Used when messages are deleted from DB and CLI history needs to be rebuilt.
648
+ *
649
+ * @param contents - Full replacement history in Gemini Content[] format
650
+ */
651
+ async replaceHistory(contents) {
652
+ if (!this.isReady()) {
653
+ throw new GeminiSDKError("Client not ready. Call start() first.");
654
+ }
655
+ const message = {
656
+ type: "control" /* CONTROL */,
657
+ control: {
658
+ subtype: "replace_history",
659
+ contents
660
+ },
661
+ session_id: this.options.sessionId
662
+ };
663
+ this.writeMessage(message);
664
+ }
629
665
  /**
630
666
  * Stop the CLI process
631
667
  */
@@ -704,12 +740,15 @@ var GeminiStreamClient = class extends EventEmitter {
704
740
  * Note: Gemini CLI does not support --settings-file parameter.
705
741
  * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
706
742
  * where GEMINI_CONFIG_DIR is set via environment variable.
743
+ *
744
+ * This method merges with existing settings.json if present, preserving
745
+ * any configuration written by the host application (e.g., tools.discoveryCommand).
707
746
  */
708
747
  async createTempSettings() {
709
748
  const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;
710
749
  if (!geminiConfigDir) {
711
750
  throw new GeminiSDKError(
712
- "GEMINI_CONFIG_DIR is required in options.env when using hooks or mcpServers. Please set options.env.GEMINI_CONFIG_DIR to a directory path."
751
+ "GEMINI_CONFIG_DIR is required in options.env when using hooks, mcpServers, tools, or context. Please set options.env.GEMINI_CONFIG_DIR to a directory path."
713
752
  );
714
753
  }
715
754
  if (!fs.existsSync(geminiConfigDir)) {
@@ -717,13 +756,32 @@ var GeminiStreamClient = class extends EventEmitter {
717
756
  this.logger.debug("Created config directory:", geminiConfigDir);
718
757
  }
719
758
  this.tempSettingsPath = path2.join(geminiConfigDir, "settings.json");
720
- const settings = {};
721
- if (this.options.hooks) {
759
+ let existingSettings = {};
760
+ if (fs.existsSync(this.tempSettingsPath)) {
761
+ try {
762
+ const content = fs.readFileSync(this.tempSettingsPath, "utf-8");
763
+ existingSettings = JSON.parse(content);
764
+ this.logger.debug("Read existing settings:", JSON.stringify(existingSettings, null, 2));
765
+ } catch (error) {
766
+ this.logger.warn("Failed to read existing settings.json, will overwrite:", error);
767
+ }
768
+ }
769
+ const settings = { ...existingSettings };
770
+ if (this.options.tools || this.options.hooks) {
771
+ const existingTools = settings.tools || {};
722
772
  settings.tools = {
723
- enableHooks: true
773
+ ...existingTools,
774
+ ...this.options.tools,
775
+ // enableHooks is set to true if hooks are configured
776
+ ...this.options.hooks ? { enableHooks: true } : {}
724
777
  };
778
+ }
779
+ if (this.options.hooks) {
725
780
  settings.hooks = this.options.hooks;
726
781
  }
782
+ if (this.options.context) {
783
+ settings.context = this.options.context;
784
+ }
727
785
  if (this.options.mcpServers) {
728
786
  settings.mcpServers = this.options.mcpServers;
729
787
  }
@@ -746,10 +804,6 @@ var GeminiStreamClient = class extends EventEmitter {
746
804
  "--output-format",
747
805
  "stream-json"
748
806
  ];
749
- if (this.options.resumeSessionFilePath) {
750
- args.push("--resume-from-file", this.options.resumeSessionFilePath);
751
- this.logger.debug("Resuming from session file:", this.options.resumeSessionFilePath);
752
- }
753
807
  if (this.options.model) {
754
808
  args.push("--model", this.options.model);
755
809
  }