@ketd/gemini-cli-sdk 0.2.3 → 0.2.5
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.cjs +58 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +55 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
var child_process = require('child_process');
|
|
4
4
|
var readline = require('readline');
|
|
5
5
|
var events = require('events');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var fs2 = require('fs');
|
|
7
|
+
var path2 = require('path');
|
|
8
|
+
var os = require('os');
|
|
8
9
|
|
|
9
10
|
function _interopNamespace(e) {
|
|
10
11
|
if (e && e.__esModule) return e;
|
|
@@ -25,8 +26,9 @@ function _interopNamespace(e) {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
28
|
-
var
|
|
29
|
-
var
|
|
29
|
+
var fs2__namespace = /*#__PURE__*/_interopNamespace(fs2);
|
|
30
|
+
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
31
|
+
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
30
32
|
|
|
31
33
|
// src/query.ts
|
|
32
34
|
|
|
@@ -411,6 +413,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
411
413
|
status = "idle" /* IDLE */;
|
|
412
414
|
initEvent = null;
|
|
413
415
|
initTimeout = null;
|
|
416
|
+
tempSettingsPath = null;
|
|
414
417
|
/**
|
|
415
418
|
* Start the Gemini CLI process
|
|
416
419
|
*/
|
|
@@ -419,6 +422,9 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
419
422
|
throw new GeminiSDKError("Process already started");
|
|
420
423
|
}
|
|
421
424
|
this.status = "running" /* RUNNING */;
|
|
425
|
+
if (this.options.hooks) {
|
|
426
|
+
await this.createTempSettings();
|
|
427
|
+
}
|
|
422
428
|
const args = this.buildCommand();
|
|
423
429
|
const env = this.buildEnv();
|
|
424
430
|
this.process = child_process.spawn("node", args, {
|
|
@@ -526,6 +532,17 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
526
532
|
}
|
|
527
533
|
this.process = null;
|
|
528
534
|
this.status = "completed" /* COMPLETED */;
|
|
535
|
+
if (this.tempSettingsPath) {
|
|
536
|
+
try {
|
|
537
|
+
fs2__namespace.unlinkSync(this.tempSettingsPath);
|
|
538
|
+
if (this.options.debug) {
|
|
539
|
+
console.log("[GeminiStreamClient] Cleaned up temp settings:", this.tempSettingsPath);
|
|
540
|
+
}
|
|
541
|
+
} catch (error) {
|
|
542
|
+
console.error("[GeminiStreamClient] Failed to clean up temp settings:", error);
|
|
543
|
+
}
|
|
544
|
+
this.tempSettingsPath = null;
|
|
545
|
+
}
|
|
529
546
|
}
|
|
530
547
|
/**
|
|
531
548
|
* Check if client is ready to send messages
|
|
@@ -551,6 +568,28 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
551
568
|
getPid() {
|
|
552
569
|
return this.process?.pid;
|
|
553
570
|
}
|
|
571
|
+
/**
|
|
572
|
+
* Create temporary settings.json for hooks configuration
|
|
573
|
+
*/
|
|
574
|
+
async createTempSettings() {
|
|
575
|
+
const tempDir = os__namespace.tmpdir();
|
|
576
|
+
this.tempSettingsPath = path2__namespace.join(tempDir, `gemini-settings-${this.options.sessionId}.json`);
|
|
577
|
+
const settings = {
|
|
578
|
+
tools: {
|
|
579
|
+
enableHooks: true
|
|
580
|
+
},
|
|
581
|
+
hooks: this.options.hooks
|
|
582
|
+
};
|
|
583
|
+
try {
|
|
584
|
+
fs2__namespace.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
585
|
+
if (this.options.debug) {
|
|
586
|
+
console.log("[GeminiStreamClient] Created temp settings:", this.tempSettingsPath);
|
|
587
|
+
console.log("[GeminiStreamClient] Settings content:", JSON.stringify(settings, null, 2));
|
|
588
|
+
}
|
|
589
|
+
} catch (error) {
|
|
590
|
+
throw new GeminiSDKError(`Failed to create temp settings file: ${error}`);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
554
593
|
/**
|
|
555
594
|
* Build CLI command arguments
|
|
556
595
|
*/
|
|
@@ -562,6 +601,15 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
562
601
|
"--output-format",
|
|
563
602
|
"stream-json"
|
|
564
603
|
];
|
|
604
|
+
if (this.tempSettingsPath) {
|
|
605
|
+
args.push("--settings-file", this.tempSettingsPath);
|
|
606
|
+
}
|
|
607
|
+
if (this.options.resumeSessionFilePath) {
|
|
608
|
+
args.push("--resume-from-file", this.options.resumeSessionFilePath);
|
|
609
|
+
if (this.options.debug) {
|
|
610
|
+
console.log("[GeminiStreamClient] Resuming from session file:", this.options.resumeSessionFilePath);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
565
613
|
if (this.options.model) {
|
|
566
614
|
args.push("--model", this.options.model);
|
|
567
615
|
}
|
|
@@ -723,17 +771,17 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
723
771
|
function findGeminiCLI(cwd = process.cwd()) {
|
|
724
772
|
if (process.env.GEMINI_CLI_PATH) {
|
|
725
773
|
const envPath = process.env.GEMINI_CLI_PATH;
|
|
726
|
-
if (
|
|
774
|
+
if (fs2__namespace.existsSync(envPath)) {
|
|
727
775
|
return envPath;
|
|
728
776
|
}
|
|
729
777
|
}
|
|
730
|
-
const localPath =
|
|
731
|
-
if (
|
|
778
|
+
const localPath = path2__namespace.join(cwd, "node_modules", "@google", "gemini-cli", "bundle", "gemini.js");
|
|
779
|
+
if (fs2__namespace.existsSync(localPath)) {
|
|
732
780
|
return localPath;
|
|
733
781
|
}
|
|
734
782
|
let currentDir = cwd;
|
|
735
783
|
for (let i = 0; i < 5; i++) {
|
|
736
|
-
const parentPath =
|
|
784
|
+
const parentPath = path2__namespace.join(
|
|
737
785
|
currentDir,
|
|
738
786
|
"node_modules",
|
|
739
787
|
"@google",
|
|
@@ -741,10 +789,10 @@ function findGeminiCLI(cwd = process.cwd()) {
|
|
|
741
789
|
"bundle",
|
|
742
790
|
"gemini.js"
|
|
743
791
|
);
|
|
744
|
-
if (
|
|
792
|
+
if (fs2__namespace.existsSync(parentPath)) {
|
|
745
793
|
return parentPath;
|
|
746
794
|
}
|
|
747
|
-
const parentDir =
|
|
795
|
+
const parentDir = path2__namespace.dirname(currentDir);
|
|
748
796
|
if (parentDir === currentDir) break;
|
|
749
797
|
currentDir = parentDir;
|
|
750
798
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","spawn","readline","EventEmitter","readline2","fs","path"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Type definitions for Gemini CLI SDK\n *\n * Based on Gemini CLI v0.21.0+ interface specification\n */\n\n/**\n * Gemini CLI configuration options\n */\nexport interface GeminiOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request */\n TOOL_USE = 'tool_use',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event\n */\nexport interface ToolUseEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_USE;\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n value: ThoughtSummary;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n };\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Options for GeminiStreamClient\n */\nexport interface GeminiStreamOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Session ID for this client instance\n * Each client manages one session\n */\n sessionId: string;\n\n /**\n * Workspace ID (optional, for tracking)\n */\n workspaceId?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Approval mode for tool execution\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn('node', [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Spawn process\n this.process = spawn('node', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n */\n async sendMessage(content: string): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.USER,\n content,\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Send an interrupt control command\n */\n async interrupt(): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'interrupt',\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","spawn","readline","EventEmitter","readline2","fs","os","path","fs2","path2"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Type definitions for Gemini CLI SDK\n *\n * Based on Gemini CLI v0.21.0+ interface specification\n */\n\n/**\n * Gemini CLI configuration options\n */\nexport interface GeminiOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request */\n TOOL_USE = 'tool_use',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event\n */\nexport interface ToolUseEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_USE;\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n value: ThoughtSummary;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n };\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Hook configuration types (from Gemini CLI)\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\nexport interface HookDefinition {\n matcher?: string;\n sequential?: boolean;\n hooks: HookConfig[];\n}\n\nexport interface HooksConfiguration {\n BeforeTool?: HookDefinition[];\n AfterTool?: HookDefinition[];\n BeforeAgent?: HookDefinition[];\n AfterAgent?: HookDefinition[];\n BeforeModel?: HookDefinition[];\n AfterModel?: HookDefinition[];\n BeforeToolSelection?: HookDefinition[];\n Notification?: HookDefinition[];\n SessionStart?: HookDefinition[];\n SessionEnd?: HookDefinition[];\n PreCompress?: HookDefinition[];\n disabled?: string[];\n}\n\n/**\n * Options for GeminiStreamClient\n */\nexport interface GeminiStreamOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Session ID for this client instance\n * Each client manages one session\n */\n sessionId: string;\n\n /**\n * Workspace ID (optional, for tracking)\n */\n workspaceId?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Approval mode for tool execution\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n\n /**\n * Hooks configuration\n * Passed to Gemini CLI via temporary settings.json\n */\n hooks?: HooksConfiguration;\n\n /**\n * Resume from a previous session file path\n * If provided, Gemini CLI will load the session history using --resume flag\n * @example '/path/to/session-2025-01-01T12-00-abc123.json'\n */\n resumeSessionFilePath?: string;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn('node', [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n private tempSettingsPath: string | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Create temporary settings.json if hooks are configured\n if (this.options.hooks) {\n await this.createTempSettings();\n }\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Spawn process\n this.process = spawn('node', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n */\n async sendMessage(content: string): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.USER,\n content,\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Send an interrupt control command\n */\n async interrupt(): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'interrupt',\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n\n // Clean up temporary settings file\n if (this.tempSettingsPath) {\n try {\n fs.unlinkSync(this.tempSettingsPath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Cleaned up temp settings:', this.tempSettingsPath);\n }\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to clean up temp settings:', error);\n }\n this.tempSettingsPath = null;\n }\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Create temporary settings.json for hooks configuration\n */\n private async createTempSettings(): Promise<void> {\n const tempDir = os.tmpdir();\n this.tempSettingsPath = path.join(tempDir, `gemini-settings-${this.options.sessionId}.json`);\n\n const settings = {\n tools: {\n enableHooks: true,\n },\n hooks: this.options.hooks,\n };\n\n try {\n fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Created temp settings:', this.tempSettingsPath);\n console.log('[GeminiStreamClient] Settings content:', JSON.stringify(settings, null, 2));\n }\n } catch (error) {\n throw new GeminiSDKError(`Failed to create temp settings file: ${error}`);\n }\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Settings file (for hooks configuration)\n if (this.tempSettingsPath) {\n args.push('--settings-file', this.tempSettingsPath);\n }\n\n // Resume from previous session file\n if (this.options.resumeSessionFilePath) {\n args.push('--resume-from-file', this.options.resumeSessionFilePath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Resuming from session file:', this.options.resumeSessionFilePath);\n }\n }\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -376,6 +376,33 @@ interface ControlInputMessage {
|
|
|
376
376
|
* Union type for input messages
|
|
377
377
|
*/
|
|
378
378
|
type JsonInputMessage = UserInputMessage | ControlInputMessage;
|
|
379
|
+
/**
|
|
380
|
+
* Hook configuration types (from Gemini CLI)
|
|
381
|
+
*/
|
|
382
|
+
interface HookConfig {
|
|
383
|
+
type: 'command';
|
|
384
|
+
command: string;
|
|
385
|
+
timeout?: number;
|
|
386
|
+
}
|
|
387
|
+
interface HookDefinition {
|
|
388
|
+
matcher?: string;
|
|
389
|
+
sequential?: boolean;
|
|
390
|
+
hooks: HookConfig[];
|
|
391
|
+
}
|
|
392
|
+
interface HooksConfiguration {
|
|
393
|
+
BeforeTool?: HookDefinition[];
|
|
394
|
+
AfterTool?: HookDefinition[];
|
|
395
|
+
BeforeAgent?: HookDefinition[];
|
|
396
|
+
AfterAgent?: HookDefinition[];
|
|
397
|
+
BeforeModel?: HookDefinition[];
|
|
398
|
+
AfterModel?: HookDefinition[];
|
|
399
|
+
BeforeToolSelection?: HookDefinition[];
|
|
400
|
+
Notification?: HookDefinition[];
|
|
401
|
+
SessionStart?: HookDefinition[];
|
|
402
|
+
SessionEnd?: HookDefinition[];
|
|
403
|
+
PreCompress?: HookDefinition[];
|
|
404
|
+
disabled?: string[];
|
|
405
|
+
}
|
|
379
406
|
/**
|
|
380
407
|
* Options for GeminiStreamClient
|
|
381
408
|
*/
|
|
@@ -428,6 +455,17 @@ interface GeminiStreamOptions {
|
|
|
428
455
|
* @default 30000
|
|
429
456
|
*/
|
|
430
457
|
initTimeout?: number;
|
|
458
|
+
/**
|
|
459
|
+
* Hooks configuration
|
|
460
|
+
* Passed to Gemini CLI via temporary settings.json
|
|
461
|
+
*/
|
|
462
|
+
hooks?: HooksConfiguration;
|
|
463
|
+
/**
|
|
464
|
+
* Resume from a previous session file path
|
|
465
|
+
* If provided, Gemini CLI will load the session history using --resume flag
|
|
466
|
+
* @example '/path/to/session-2025-01-01T12-00-abc123.json'
|
|
467
|
+
*/
|
|
468
|
+
resumeSessionFilePath?: string;
|
|
431
469
|
}
|
|
432
470
|
|
|
433
471
|
/**
|
|
@@ -591,6 +629,7 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
591
629
|
private status;
|
|
592
630
|
private initEvent;
|
|
593
631
|
private initTimeout;
|
|
632
|
+
private tempSettingsPath;
|
|
594
633
|
constructor(options: GeminiStreamOptions);
|
|
595
634
|
/**
|
|
596
635
|
* Start the Gemini CLI process
|
|
@@ -624,6 +663,10 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
624
663
|
* Get process PID
|
|
625
664
|
*/
|
|
626
665
|
getPid(): number | undefined;
|
|
666
|
+
/**
|
|
667
|
+
* Create temporary settings.json for hooks configuration
|
|
668
|
+
*/
|
|
669
|
+
private createTempSettings;
|
|
627
670
|
/**
|
|
628
671
|
* Build CLI command arguments
|
|
629
672
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -376,6 +376,33 @@ interface ControlInputMessage {
|
|
|
376
376
|
* Union type for input messages
|
|
377
377
|
*/
|
|
378
378
|
type JsonInputMessage = UserInputMessage | ControlInputMessage;
|
|
379
|
+
/**
|
|
380
|
+
* Hook configuration types (from Gemini CLI)
|
|
381
|
+
*/
|
|
382
|
+
interface HookConfig {
|
|
383
|
+
type: 'command';
|
|
384
|
+
command: string;
|
|
385
|
+
timeout?: number;
|
|
386
|
+
}
|
|
387
|
+
interface HookDefinition {
|
|
388
|
+
matcher?: string;
|
|
389
|
+
sequential?: boolean;
|
|
390
|
+
hooks: HookConfig[];
|
|
391
|
+
}
|
|
392
|
+
interface HooksConfiguration {
|
|
393
|
+
BeforeTool?: HookDefinition[];
|
|
394
|
+
AfterTool?: HookDefinition[];
|
|
395
|
+
BeforeAgent?: HookDefinition[];
|
|
396
|
+
AfterAgent?: HookDefinition[];
|
|
397
|
+
BeforeModel?: HookDefinition[];
|
|
398
|
+
AfterModel?: HookDefinition[];
|
|
399
|
+
BeforeToolSelection?: HookDefinition[];
|
|
400
|
+
Notification?: HookDefinition[];
|
|
401
|
+
SessionStart?: HookDefinition[];
|
|
402
|
+
SessionEnd?: HookDefinition[];
|
|
403
|
+
PreCompress?: HookDefinition[];
|
|
404
|
+
disabled?: string[];
|
|
405
|
+
}
|
|
379
406
|
/**
|
|
380
407
|
* Options for GeminiStreamClient
|
|
381
408
|
*/
|
|
@@ -428,6 +455,17 @@ interface GeminiStreamOptions {
|
|
|
428
455
|
* @default 30000
|
|
429
456
|
*/
|
|
430
457
|
initTimeout?: number;
|
|
458
|
+
/**
|
|
459
|
+
* Hooks configuration
|
|
460
|
+
* Passed to Gemini CLI via temporary settings.json
|
|
461
|
+
*/
|
|
462
|
+
hooks?: HooksConfiguration;
|
|
463
|
+
/**
|
|
464
|
+
* Resume from a previous session file path
|
|
465
|
+
* If provided, Gemini CLI will load the session history using --resume flag
|
|
466
|
+
* @example '/path/to/session-2025-01-01T12-00-abc123.json'
|
|
467
|
+
*/
|
|
468
|
+
resumeSessionFilePath?: string;
|
|
431
469
|
}
|
|
432
470
|
|
|
433
471
|
/**
|
|
@@ -591,6 +629,7 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
591
629
|
private status;
|
|
592
630
|
private initEvent;
|
|
593
631
|
private initTimeout;
|
|
632
|
+
private tempSettingsPath;
|
|
594
633
|
constructor(options: GeminiStreamOptions);
|
|
595
634
|
/**
|
|
596
635
|
* Start the Gemini CLI process
|
|
@@ -624,6 +663,10 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
624
663
|
* Get process PID
|
|
625
664
|
*/
|
|
626
665
|
getPid(): number | undefined;
|
|
666
|
+
/**
|
|
667
|
+
* Create temporary settings.json for hooks configuration
|
|
668
|
+
*/
|
|
669
|
+
private createTempSettings;
|
|
627
670
|
/**
|
|
628
671
|
* Build CLI command arguments
|
|
629
672
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import * as readline from 'readline';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
4
|
+
import * as fs2 from 'fs';
|
|
5
|
+
import * as path2 from 'path';
|
|
6
|
+
import * as os from 'os';
|
|
6
7
|
|
|
7
8
|
// src/query.ts
|
|
8
9
|
|
|
@@ -387,6 +388,7 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
387
388
|
status = "idle" /* IDLE */;
|
|
388
389
|
initEvent = null;
|
|
389
390
|
initTimeout = null;
|
|
391
|
+
tempSettingsPath = null;
|
|
390
392
|
/**
|
|
391
393
|
* Start the Gemini CLI process
|
|
392
394
|
*/
|
|
@@ -395,6 +397,9 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
395
397
|
throw new GeminiSDKError("Process already started");
|
|
396
398
|
}
|
|
397
399
|
this.status = "running" /* RUNNING */;
|
|
400
|
+
if (this.options.hooks) {
|
|
401
|
+
await this.createTempSettings();
|
|
402
|
+
}
|
|
398
403
|
const args = this.buildCommand();
|
|
399
404
|
const env = this.buildEnv();
|
|
400
405
|
this.process = spawn("node", args, {
|
|
@@ -502,6 +507,17 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
502
507
|
}
|
|
503
508
|
this.process = null;
|
|
504
509
|
this.status = "completed" /* COMPLETED */;
|
|
510
|
+
if (this.tempSettingsPath) {
|
|
511
|
+
try {
|
|
512
|
+
fs2.unlinkSync(this.tempSettingsPath);
|
|
513
|
+
if (this.options.debug) {
|
|
514
|
+
console.log("[GeminiStreamClient] Cleaned up temp settings:", this.tempSettingsPath);
|
|
515
|
+
}
|
|
516
|
+
} catch (error) {
|
|
517
|
+
console.error("[GeminiStreamClient] Failed to clean up temp settings:", error);
|
|
518
|
+
}
|
|
519
|
+
this.tempSettingsPath = null;
|
|
520
|
+
}
|
|
505
521
|
}
|
|
506
522
|
/**
|
|
507
523
|
* Check if client is ready to send messages
|
|
@@ -527,6 +543,28 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
527
543
|
getPid() {
|
|
528
544
|
return this.process?.pid;
|
|
529
545
|
}
|
|
546
|
+
/**
|
|
547
|
+
* Create temporary settings.json for hooks configuration
|
|
548
|
+
*/
|
|
549
|
+
async createTempSettings() {
|
|
550
|
+
const tempDir = os.tmpdir();
|
|
551
|
+
this.tempSettingsPath = path2.join(tempDir, `gemini-settings-${this.options.sessionId}.json`);
|
|
552
|
+
const settings = {
|
|
553
|
+
tools: {
|
|
554
|
+
enableHooks: true
|
|
555
|
+
},
|
|
556
|
+
hooks: this.options.hooks
|
|
557
|
+
};
|
|
558
|
+
try {
|
|
559
|
+
fs2.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
560
|
+
if (this.options.debug) {
|
|
561
|
+
console.log("[GeminiStreamClient] Created temp settings:", this.tempSettingsPath);
|
|
562
|
+
console.log("[GeminiStreamClient] Settings content:", JSON.stringify(settings, null, 2));
|
|
563
|
+
}
|
|
564
|
+
} catch (error) {
|
|
565
|
+
throw new GeminiSDKError(`Failed to create temp settings file: ${error}`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
530
568
|
/**
|
|
531
569
|
* Build CLI command arguments
|
|
532
570
|
*/
|
|
@@ -538,6 +576,15 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
538
576
|
"--output-format",
|
|
539
577
|
"stream-json"
|
|
540
578
|
];
|
|
579
|
+
if (this.tempSettingsPath) {
|
|
580
|
+
args.push("--settings-file", this.tempSettingsPath);
|
|
581
|
+
}
|
|
582
|
+
if (this.options.resumeSessionFilePath) {
|
|
583
|
+
args.push("--resume-from-file", this.options.resumeSessionFilePath);
|
|
584
|
+
if (this.options.debug) {
|
|
585
|
+
console.log("[GeminiStreamClient] Resuming from session file:", this.options.resumeSessionFilePath);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
541
588
|
if (this.options.model) {
|
|
542
589
|
args.push("--model", this.options.model);
|
|
543
590
|
}
|
|
@@ -699,17 +746,17 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
699
746
|
function findGeminiCLI(cwd = process.cwd()) {
|
|
700
747
|
if (process.env.GEMINI_CLI_PATH) {
|
|
701
748
|
const envPath = process.env.GEMINI_CLI_PATH;
|
|
702
|
-
if (
|
|
749
|
+
if (fs2.existsSync(envPath)) {
|
|
703
750
|
return envPath;
|
|
704
751
|
}
|
|
705
752
|
}
|
|
706
|
-
const localPath =
|
|
707
|
-
if (
|
|
753
|
+
const localPath = path2.join(cwd, "node_modules", "@google", "gemini-cli", "bundle", "gemini.js");
|
|
754
|
+
if (fs2.existsSync(localPath)) {
|
|
708
755
|
return localPath;
|
|
709
756
|
}
|
|
710
757
|
let currentDir = cwd;
|
|
711
758
|
for (let i = 0; i < 5; i++) {
|
|
712
|
-
const parentPath =
|
|
759
|
+
const parentPath = path2.join(
|
|
713
760
|
currentDir,
|
|
714
761
|
"node_modules",
|
|
715
762
|
"@google",
|
|
@@ -717,10 +764,10 @@ function findGeminiCLI(cwd = process.cwd()) {
|
|
|
717
764
|
"bundle",
|
|
718
765
|
"gemini.js"
|
|
719
766
|
);
|
|
720
|
-
if (
|
|
767
|
+
if (fs2.existsSync(parentPath)) {
|
|
721
768
|
return parentPath;
|
|
722
769
|
}
|
|
723
|
-
const parentDir =
|
|
770
|
+
const parentDir = path2.dirname(currentDir);
|
|
724
771
|
if (parentDir === currentDir) break;
|
|
725
772
|
currentDir = parentDir;
|
|
726
773
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","EventEmitter","spawn","readline2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Type definitions for Gemini CLI SDK\n *\n * Based on Gemini CLI v0.21.0+ interface specification\n */\n\n/**\n * Gemini CLI configuration options\n */\nexport interface GeminiOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request */\n TOOL_USE = 'tool_use',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event\n */\nexport interface ToolUseEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_USE;\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n value: ThoughtSummary;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n };\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Options for GeminiStreamClient\n */\nexport interface GeminiStreamOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Session ID for this client instance\n * Each client manages one session\n */\n sessionId: string;\n\n /**\n * Workspace ID (optional, for tracking)\n */\n workspaceId?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Approval mode for tool execution\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn('node', [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Spawn process\n this.process = spawn('node', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n */\n async sendMessage(content: string): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.USER,\n content,\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Send an interrupt control command\n */\n async interrupt(): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'interrupt',\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","EventEmitter","spawn","readline2","fs","path"],"mappings":";;;;;;;;;;AAyIO,IAAK,mBAAA,qBAAAA,oBAAAA,KAAL;AAEL,EAAAA,qBAAA,MAAA,CAAA,GAAO,MAAA;AAGP,EAAAA,qBAAA,SAAA,CAAA,GAAU,SAAA;AAGV,EAAAA,qBAAA,UAAA,CAAA,GAAW,UAAA;AAGX,EAAAA,qBAAA,aAAA,CAAA,GAAc,aAAA;AAGd,EAAAA,qBAAA,SAAA,CAAA,GAAU,SAAA;AAGV,EAAAA,qBAAA,OAAA,CAAA,GAAQ,OAAA;AAGR,EAAAA,qBAAA,QAAA,CAAA,GAAS,QAAA;AAIT,EAAAA,qBAAA,SAAA,CAAA,GAAU,SAAA;AAGV,EAAAA,qBAAA,UAAA,CAAA,GAAW,UAAA;AAGX,EAAAA,qBAAA,YAAA,CAAA,GAAa,YAAA;AA9BH,EAAA,OAAAA,oBAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;AAqML,IAAK,QAAA,qBAAAC,SAAAA,KAAL;AAEL,EAAAA,SAAAA,CAAAA,SAAAA,CAAA,aAAU,CAAA,CAAA,GAAV,SAAA;AAGA,EAAAA,SAAAA,CAAAA,SAAAA,CAAA,mBAAgB,CAAA,CAAA,GAAhB,eAAA;AAGA,EAAAA,SAAAA,CAAAA,SAAAA,CAAA,kBAAe,CAAA,CAAA,GAAf,cAAA;AAGA,EAAAA,SAAAA,CAAAA,SAAAA,CAAA,sBAAmB,GAAA,CAAA,GAAnB,kBAAA;AAXU,EAAA,OAAAA,SAAAA;AAAA,CAAA,EAAA,QAAA,IAAA,EAAA;AAiBL,IAAK,aAAA,qBAAAC,cAAAA,KAAL;AAEL,EAAAA,eAAA,MAAA,CAAA,GAAO,MAAA;AAGP,EAAAA,eAAA,SAAA,CAAA,GAAU,SAAA;AAGV,EAAAA,eAAA,WAAA,CAAA,GAAY,WAAA;AAGZ,EAAAA,eAAA,WAAA,CAAA,GAAY,WAAA;AAGZ,EAAAA,eAAA,OAAA,CAAA,GAAQ,OAAA;AAdE,EAAA,OAAAA,cAAAA;AAAA,CAAA,EAAA,aAAA,IAAA,EAAA;AAoBL,IAAM,cAAA,GAAN,MAAM,eAAA,SAAuB,KAAA,CAAM;AAAA,EACxC,WAAA,CACE,OAAA,EACO,IAAA,EACA,OAAA,EACP;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHN,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGP,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AAEZ,IAAA,IAAI,OAAQ,KAAA,CAAc,iBAAA,KAAsB,UAAA,EAAY;AAC1D,MAAC,KAAA,CAAc,iBAAA,CAAkB,IAAA,EAAM,eAAc,CAAA;AAAA,IACvD;AAAA,EACF;AACF;AA2CO,IAAK,oBAAA,qBAAAC,qBAAAA,KAAL;AAEL,EAAAA,sBAAA,MAAA,CAAA,GAAO,MAAA;AAGP,EAAAA,sBAAA,SAAA,CAAA,GAAU,SAAA;AALA,EAAA,OAAAA,qBAAAA;AAAA,CAAA,EAAA,oBAAA,IAAA,EAAA;;;AC7ZZ,SAAS,YAAA,CAAa,SAAwB,MAAA,EAA0B;AACtE,EAAA,MAAM,OAAiB,EAAC;AAGxB,EAAA,IAAA,CAAK,IAAA,CAAK,mBAAmB,aAAa,CAAA;AAG1C,EAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,IAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,OAAA,CAAQ,KAAK,CAAA;AAAA,EACpC;AAGA,EAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,IAAA,IAAA,CAAK,IAAA,CAAK,iBAAA,EAAmB,OAAA,CAAQ,YAAY,CAAA;AAAA,EACnD;AAGA,EAAA,IAAI,OAAA,CAAQ,YAAA,IAAgB,OAAA,CAAQ,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3D,IAAA,IAAA,CAAK,KAAK,iBAAA,EAAmB,OAAA,CAAQ,YAAA,CAAa,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EAC7D;AAGA,EAAA,IAAI,OAAA,CAAQ,qBAAA,IAAyB,OAAA,CAAQ,qBAAA,CAAsB,SAAS,CAAA,EAAG;AAC7E,IAAA,IAAA,CAAK,KAAK,4BAAA,EAA8B,OAAA,CAAQ,qBAAA,CAAsB,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EACjF;AAGA,EAAA,IAAI,QAAQ,eAAA,EAAiB;AAC3B,IAAA,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,OAAA,CAAQ,eAAe,CAAA;AAAA,EAC/C;AAGA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,IAAA,CAAK,KAAK,WAAW,CAAA;AAAA,EACvB;AAGA,EAAA,IAAI,OAAA,CAAQ,kBAAA,IAAsB,OAAA,CAAQ,kBAAA,CAAmB,SAAS,CAAA,EAAG;AACvE,IAAA,IAAA,CAAK,KAAK,uBAAA,EAAyB,OAAA,CAAQ,kBAAA,CAAmB,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EACzE;AAGA,EAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,IAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAAA,EACrB;AAGA,EAAA,IAAA,CAAK,KAAK,MAAM,CAAA;AAEhB,EAAA,OAAO,IAAA;AACT;AAKA,SAAS,SAAS,OAAA,EAA2C;AAC3D,EAAA,MAAM,GAAA,GAAyB;AAAA,IAC7B,GAAG,OAAA,CAAQ,GAAA;AAAA,IACX,GAAG,OAAA,CAAQ;AAAA,GACb;AAKA,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,MAAA,EAAQ,UAAA,CAAW,KAAK,CAAA;AACtD,EAAA,MAAM,WAAA,GAAc,aAAA,IAAiB,GAAA,CAAI,yBAAA,KAA8B,MAAA;AAGvE,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,IAAI,WAAA,EAAa;AAEf,MAAA,GAAA,CAAI,iBAAiB,OAAA,CAAQ,MAAA;AAC7B,MAAA,GAAA,CAAI,yBAAA,GAA4B,MAAA;AAChC,MAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,QAAA,OAAA,CAAQ,GAAA,CAAI,iDAAiD,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG,EAAE,IAAI,KAAK,CAAA;AAAA,MACtG;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,GAAA,CAAI,iBAAiB,OAAA,CAAQ,MAAA;AAC7B,MAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,QAAA,OAAA,CAAQ,GAAA,CAAI,gDAAgD,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG,EAAE,IAAI,KAAK,CAAA;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAIA,EAAA,IAAI,CAAC,WAAA,IAAe,GAAA,CAAI,cAAA,EAAgB;AACtC,IAAA,OAAO,GAAA,CAAI,cAAA;AACX,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,OAAA,CAAQ,IAAI,qEAAqE,CAAA;AAAA,IACnF;AAAA,EACF;AAGA,EAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,IAAA,GAAA,CAAI,KAAA,GAAQ,GAAA;AACZ,IAAA,OAAA,CAAQ,IAAI,kCAAA,EAAoC;AAAA,MAC9C,cAAA,EAAgB,GAAA,CAAI,cAAA,GAAiB,KAAA,GAAQ,MAAA;AAAA,MAC7C,cAAA,EAAgB,GAAA,CAAI,cAAA,GAAiB,KAAA,GAAQ,MAAA;AAAA,MAC7C,2BAA2B,GAAA,CAAI,yBAAA;AAAA,MAC/B,mBAAmB,GAAA,CAAI;AAAA,KACxB,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,GAAA;AACT;AA0BA,gBAAuB,KAAA,CACrB,QACA,OAAA,EACiC;AAEjC,EAAA,IAAI,CAAC,QAAQ,eAAA,EAAiB;AAC5B,IAAA,MAAM,IAAI,eAAe,6BAA6B,CAAA;AAAA,EACxD;AAEA,EAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,IAAU,CAAC,OAAA,CAAQ,IAAI,cAAA,EAAgB;AAClD,IAAA,MAAM,IAAI,cAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,OAAA,EAAS,MAAM,CAAA;AACzC,EAAA,MAAM,GAAA,GAAM,SAAS,OAAO,CAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAGvC,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgB,MAAM,MAAA,EAAQ,CAAC,QAAQ,eAAA,EAAiB,GAAG,IAAI,CAAA,EAAG;AAAA,MAChE,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC9B,GAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,cAAA,CAAe,oCAAA,EAAsC,MAAA,EAAW,KAAK,CAAA;AAAA,EACjF;AAGA,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,aAAA,CAAc,MAAA,EAAQ,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,KAAiB;AACjD,IAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,OAAA,CAAQ,KAAA,CAAM,sBAAA,EAAwB,IAAA,CAAK,QAAA,EAAU,CAAA;AAAA,IACvD;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,SAAA,GAAY,WAAW,MAAM;AAC3B,MAAA,aAAA,CAAc,KAAK,SAAS,CAAA;AAAA,IAC9B,CAAA,EAAG,QAAQ,OAAO,CAAA;AAAA,EACpB;AAGA,EAAA,MAAM,KAAc,QAAA,CAAA,eAAA,CAAgB;AAAA,IAClC,OAAO,aAAA,CAAc,MAAA;AAAA,IACrB,SAAA,EAAW;AAAA,GACZ,CAAA;AAGD,EAAA,IAAI,gBAAA,GAAmB,KAAA;AAEvB,EAAA,IAAI;AAEF,IAAA,WAAA,MAAiB,QAAQ,EAAA,EAAI;AAC3B,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,QAAA,gBAAA,GAAmB,IAAA;AACnB,QAAA,MAAM,KAAA;AAAA,MACR,SAAS,UAAA,EAAY;AAEnB,QAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,UAAA,OAAA,CAAQ,KAAA,CAAM,2CAA2C,IAAI,CAAA;AAC7D,UAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,UAAU,CAAA;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,cAAA,CAAe,uCAAA,EAAyC,MAAA,EAAW,KAAK,CAAA;AAAA,EACpF,CAAA,SAAE;AAEA,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB;AAAA,EACF;AAGA,EAAA,MAAM,WAAW,MAAM,IAAI,OAAA,CAAgB,CAAC,SAAS,MAAA,KAAW;AAC9D,IAAA,aAAA,CAAc,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,EAAM,MAAA,KAAW;AACzC,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAA;AAAA,UACE,IAAI,cAAA;AAAA,YACF,6CAA6C,MAAM,CAAA,CAAA;AAAA,YAAA,GAAA;AAAA;AAErD,SACF;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,IAAA,IAAA,CAAA,qBAA8B;AAAA,MACxC;AAAA,IACF,CAAC,CAAA;AAED,IAAA,aAAA,CAAc,EAAA,CAAG,OAAA,EAAS,CAAC,KAAA,KAAU;AACnC,MAAA,MAAA,CAAO,IAAI,cAAA,CAAe,0BAAA,EAA4B,MAAA,EAAW,KAAK,CAAC,CAAA;AAAA,IACzE,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AAGD,EAAA,IAAI,QAAA,KAAA,CAAA,gBAA+B;AACjC,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAO,YAAY,EAAE,QAAA,EAAS;AAC1D,IAAA,MAAM,IAAI,cAAA;AAAA,MACR,CAAA,4BAAA,EAA+B,QAAQ,CAAA,EAAG,YAAA,GAAe;AAAA,EAAK,YAAY,KAAK,EAAE,CAAA,CAAA;AAAA,MACjF,QAAA;AAAA,MACA,EAAE,QAAQ,YAAA;AAAa,KACzB;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAO,YAAY,EAAE,QAAA,EAAS;AAC1D,IAAA,MAAM,IAAI,cAAA;AAAA,MACR,oCAAA;AAAA,MACA,MAAA;AAAA,MACA,EAAE,QAAQ,YAAA;AAAa,KACzB;AAAA,EACF;AACF;AChOO,IAAM,YAAA,GAAN,cAA2B,YAAA,CAAa;AAAA,EAI7C,YAAoB,OAAA,EAAwB;AAC1C,IAAA,KAAA,EAAM;AADY,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAEpB;AAAA,EALQ,MAAA,GAAA,MAAA;AAAA,EACA,gBAAA,GAAkC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY1C,OAAO,OAAO,MAAA,EAAiD;AAC7D,IAAA,IAAA,CAAK,MAAA,GAAA,SAAA;AACL,IAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,MAAM,CAAA;AAE/B,IAAA,IAAI;AACF,MAAA,WAAA,MAAiB,KAAA,IAAS,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,OAAO,CAAA,EAAG;AAErD,QAAA,IAAI,MAAM,IAAA,KAAA,MAAA,aAAmC;AAC3C,UAAA,IAAA,CAAK,mBAAmB,KAAA,CAAM,UAAA;AAC9B,UAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,KAAA,CAAM,UAAU,CAAA;AAAA,QACvC;AAGA,QAAA,IAAI,KAAA,CAAM,IAAA,KAAA,UAAA,mBAAyC,IAAA,CAAK,OAAA,CAAQ,mBAAA,EAAqB;AACnF,UAAA,MAAM,iBAAA,GAAoB;AAAA,YACxB,QAAQ,KAAA,CAAM,OAAA;AAAA,YACd,UAAU,KAAA,CAAM,SAAA;AAAA,YAChB,YAAY,KAAA,CAAM,UAAA;AAAA,YAClB,WAAW,KAAA,CAAM;AAAA,WACnB;AAEA,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,oBAAoB,iBAAiB,CAAA;AAGzE,YAAA,IAAA,CAAK,KAAK,YAAA,EAAc;AAAA,cACtB,OAAA,EAAS,iBAAA;AAAA,cACT;AAAA,aACD,CAAA;AAKD,YAAA,IAAI,CAAC,SAAS,QAAA,EAAU;AACtB,cAAA,IAAA,CAAK,KAAK,SAAA,EAAW;AAAA,gBACnB,IAAA,EAAA,OAAA;AAAA,gBACA,QAAA,EAAU,SAAA;AAAA,gBACV,OAAA,EAAS,CAAA,KAAA,EAAQ,KAAA,CAAM,SAAS,CAAA,gEAAA,CAAA;AAAA,gBAChC,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,eACnC,CAAA;AAAA,YACH;AAAA,UACF,SAAS,KAAA,EAAO;AACd,YAAA,IAAA,CAAK,KAAK,OAAA,EAAS;AAAA,cACjB,OAAA,EAAS,CAAA,mCAAA,EAAsC,KAAA,CAAM,SAAS,CAAA,CAAA;AAAA,cAC9D;AAAA,aACD,CAAA;AAAA,UAEH;AAAA,QACF;AAGA,QAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AAGxB,QAAA,MAAM,KAAA;AAGN,QAAA,IAAI,MAAM,IAAA,KAAA,QAAA,eAAqC;AAC7C,UAAA,IAAA,CAAK,MAAA,GACH,MAAM,MAAA,KAAW,SAAA,GAAA,WAAA,mBAAA,OAAA;AACnB,UAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,MAAM,CAAA;AAAA,QACjC;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,GAAA,OAAA;AACL,MAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,MAAM,CAAA;AAC/B,MAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AACxB,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAM,MAAA,EAAsC;AAChD,IAAA,MAAM,MAAA,GAAsB;AAAA,MAC1B,SAAA,EAAW,EAAA;AAAA,MACX,KAAA,EAAO,EAAA;AAAA,MACP,QAAA,EAAU,EAAA;AAAA,MACV,WAAW,EAAC;AAAA,MACZ,MAAA,EAAQ;AAAA,KACV;AAEA,IAAA,MAAM,YAAA,uBAAmB,GAAA,EAQvB;AAEF,IAAA,WAAA,MAAiB,KAAA,IAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG;AAC7C,MAAA,QAAQ,MAAM,IAAA;AAAM,QAClB,KAAA,MAAA;AACE,UAAA,MAAA,CAAO,YAAY,KAAA,CAAM,UAAA;AACzB,UAAA,MAAA,CAAO,QAAQ,KAAA,CAAM,KAAA;AACrB,UAAA;AAAA,QAEF,KAAA,SAAA;AACE,UAAA,IAAI,KAAA,CAAM,SAAS,WAAA,EAAa;AAC9B,YAAA,MAAA,CAAO,YAAY,KAAA,CAAM,OAAA;AAAA,UAC3B;AACA,UAAA;AAAA,QAEF,KAAA,UAAA;AACE,UAAA,YAAA,CAAa,GAAA,CAAI,MAAM,OAAA,EAAS;AAAA,YAC9B,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,SAAS,KAAA,CAAM,OAAA;AAAA,YACf,YAAY,KAAA,CAAM;AAAA,WACnB,CAAA;AACD,UAAA;AAAA,QAEF,KAAA,aAAA;AACE,UAAA;AACE,YAAA,MAAM,QAAA,GAAW,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAC/C,YAAA,IAAI,QAAA,EAAU;AACZ,cAAA,QAAA,CAAS,MAAA,GAAS,KAAA;AAClB,cAAA,MAAA,CAAO,UAAU,IAAA,CAAK;AAAA,gBACpB,WAAW,QAAA,CAAS,SAAA;AAAA,gBACpB,SAAS,QAAA,CAAS,OAAA;AAAA,gBAClB,YAAY,QAAA,CAAS,UAAA;AAAA,gBACrB,MAAA,EAAQ;AAAA,kBACN,QAAQ,KAAA,CAAM,MAAA;AAAA,kBACd,QAAQ,KAAA,CAAM,MAAA;AAAA,kBACd,OAAO,KAAA,CAAM;AAAA;AACf,eACD,CAAA;AAAA,YACH;AAAA,UACF;AACA,UAAA;AAAA,QAEF,KAAA,QAAA;AACE,UAAA,MAAA,CAAO,SAAS,KAAA,CAAM,MAAA;AACtB,UAAA,MAAA,CAAO,QAAQ,KAAA,CAAM,KAAA;AACrB,UAAA,IAAI,MAAM,KAAA,EAAO;AACf,YAAA,MAAA,CAAO,QAAQ,KAAA,CAAM,KAAA;AAAA,UACvB;AACA,UAAA;AAAA,QAEF,KAAA,OAAA;AAEE,UAAA,IAAA,CAAK,IAAA,CAAK,WAAW,KAAK,CAAA;AAC1B,UAAA;AAAA;AACJ,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA2B;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAA8B;AAC5B,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAA,EAAuC;AAChD,IAAA,IAAA,CAAK,UAAU,EAAE,GAAG,IAAA,CAAK,OAAA,EAAS,GAAG,OAAA,EAAQ;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAsC;AACpC,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,OAAA,EAAQ;AAAA,EAC3B;AACF;ACnKO,IAAM,kBAAA,GAAN,cAAiCC,YAAAA,CAAa;AAAA,EASnD,YAAoB,OAAA,EAA8B;AAChD,IAAA,KAAA,EAAM;AADY,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAIlB,IAAA,IAAI,CAAC,QAAQ,eAAA,EAAiB;AAC5B,MAAA,MAAM,IAAI,eAAe,6BAA6B,CAAA;AAAA,IACxD;AACA,IAAA,IAAI,CAAC,QAAQ,SAAA,EAAW;AACtB,MAAA,MAAM,IAAI,eAAe,uBAAuB,CAAA;AAAA,IAClD;AAAA,EACF;AAAA,EAlBQ,OAAA,GAA+B,IAAA;AAAA,EAC/B,WAAA,GAA+B,IAAA;AAAA,EAC/B,iBAAA,GAA+C,IAAA;AAAA,EAC/C,MAAA,GAAA,MAAA;AAAA,EACA,SAAA,GAA8B,IAAA;AAAA,EAC9B,WAAA,GAAqC,IAAA;AAAA,EACrC,gBAAA,GAAkC,IAAA;AAAA;AAAA;AAAA;AAAA,EAiB1C,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,MAAM,IAAI,eAAe,yBAAyB,CAAA;AAAA,IACpD;AAEA,IAAA,IAAA,CAAK,MAAA,GAAA,SAAA;AAGL,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,MAAM,KAAK,kBAAA,EAAmB;AAAA,IAChC;AAGA,IAAA,MAAM,IAAA,GAAO,KAAK,YAAA,EAAa;AAG/B,IAAA,MAAM,GAAA,GAAM,KAAK,QAAA,EAAS;AAG1B,IAAA,IAAA,CAAK,OAAA,GAAUC,KAAAA,CAAM,MAAA,EAAQ,IAAA,EAAM;AAAA,MACjC,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC9B,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,QAAQ,GAAA,EAAI;AAAA,MACrC;AAAA,KACD,CAAA;AAGD,IAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,MAAA,EAAQ,CAAC,MAAM,MAAA,KAAW;AACxC,MAAA,IAAA,CAAK,iBAAA,CAAkB,MAAM,MAAM,CAAA;AAAA,IACrC,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,OAAA,EAAS,CAAC,KAAA,KAAU;AAClC,MAAA,IAAA,CAAK,mBAAmB,KAAK,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAA,CAAK,WAAA,GAAc,KAAK,OAAA,CAAQ,KAAA;AAEhC,MAAA,IAAA,CAAK,WAAA,CAAY,mBAAmB,OAAO,CAAA;AAAA,IAG7C,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,eAAe,4BAA4B,CAAA;AAAA,IACvD;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,oBAA6BC,QAAA,CAAA,eAAA,CAAgB;AAAA,QAChD,KAAA,EAAO,KAAK,OAAA,CAAQ,MAAA;AAAA,QACpB,QAAA,EAAU;AAAA;AAAA,OACX,CAAA;AAGD,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,eAAe,6BAA6B,CAAA;AAAA,IACxD;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAU;AAExC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,KAAA,CAAM,QAAA,EAAU,CAAA;AAAA,QAChE;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAGnB,IAAA,MAAM,KAAK,WAAA,EAAY;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,OAAA,EAAgC;AAChD,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAQ,EAAG;AACnB,MAAA,MAAM,IAAI,eAAe,uCAAuC,CAAA;AAAA,IAClE;AAEA,IAAA,MAAM,OAAA,GAA4B;AAAA,MAChC,IAAA,EAAA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA,EAAY,KAAK,OAAA,CAAQ;AAAA,KAC3B;AAEA,IAAA,IAAA,CAAK,aAAa,OAAO,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,GAA2B;AAC/B,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAQ,EAAG;AACnB,MAAA,MAAM,IAAI,eAAe,uCAAuC,CAAA;AAAA,IAClE;AAEA,IAAA,MAAM,OAAA,GAA4B;AAAA,MAChC,IAAA,EAAA,SAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,OAAA,EAAS;AAAA,OACX;AAAA,MACA,UAAA,EAAY,KAAK,OAAA,CAAQ;AAAA,KAC3B;AAEA,IAAA,IAAA,CAAK,aAAa,OAAO,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAK,OAAA,GAAkB,GAAA,EAAqB;AAChD,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,YAAA,CAAa,KAAK,WAAW,CAAA;AAC7B,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAGA,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,YAAY,GAAA,EAAI;AACrB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAGA,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAC7B,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B;AAGA,IAAA,MAAM,QAAQ,IAAA,CAAK;AAAA,MACjB,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AAC7B,QAAA,IAAI,KAAK,OAAA,EAAS;AAChB,UAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,MAAA,EAAQ,MAAM,SAAS,CAAA;AAAA,QAC3C,CAAA,MAAO;AACL,UAAA,OAAA,EAAQ;AAAA,QACV;AAAA,MACF,CAAC,CAAA;AAAA,MACD,IAAI,OAAA,CAAc,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,OAAO,CAAC;AAAA,KAC5D,CAAA;AAGD,IAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACxC,MAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,SAAS,CAAA;AAG3B,MAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,GAAI,CAAC,CAAA;AAGxD,MAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACxC,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,SAAS,CAAA;AAAA,MAC7B;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,MAAA,GAAA,WAAA;AAGL,IAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,MAAA,IAAI;AACF,QAAGC,GAAA,CAAA,UAAA,CAAW,KAAK,gBAAgB,CAAA;AACnC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,GAAA,CAAI,gDAAA,EAAkD,IAAA,CAAK,gBAAgB,CAAA;AAAA,QACrF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,0DAA0D,KAAK,CAAA;AAAA,MAC/E;AACA,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAmB;AACjB,IAAA,OAAO,IAAA,CAAK,MAAA,KAAA,SAAA,kBAAoC,IAAA,CAAK,SAAA,KAAc,IAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA2B;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAA6B;AAC3B,IAAA,OAAO,KAAK,OAAA,EAAS,GAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAA,GAAoC;AAChD,IAAA,MAAM,UAAa,EAAA,CAAA,MAAA,EAAO;AAC1B,IAAA,IAAA,CAAK,mBAAwBC,KAAA,CAAA,IAAA,CAAK,OAAA,EAAS,mBAAmB,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,KAAA,CAAO,CAAA;AAE3F,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,KAAA,EAAO;AAAA,QACL,WAAA,EAAa;AAAA,OACf;AAAA,MACA,KAAA,EAAO,KAAK,OAAA,CAAQ;AAAA,KACtB;AAEA,IAAA,IAAI;AACF,MAAGD,GAAA,CAAA,aAAA,CAAc,KAAK,gBAAA,EAAkB,IAAA,CAAK,UAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA,EAAG,OAAO,CAAA;AAClF,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,6CAAA,EAA+C,IAAA,CAAK,gBAAgB,CAAA;AAChF,QAAA,OAAA,CAAQ,IAAI,wCAAA,EAA0C,IAAA,CAAK,UAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,MACzF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,cAAA,CAAe,CAAA,qCAAA,EAAwC,KAAK,CAAA,CAAE,CAAA;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAA,GAAyB;AAC/B,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,KAAK,OAAA,CAAQ,eAAA;AAAA,MACb,qBAAA;AAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACF;AAGA,IAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,MAAA,IAAA,CAAK,IAAA,CAAK,iBAAA,EAAmB,IAAA,CAAK,gBAAgB,CAAA;AAAA,IACpD;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,qBAAA,EAAuB;AACtC,MAAA,IAAA,CAAK,IAAA,CAAK,oBAAA,EAAsB,IAAA,CAAK,OAAA,CAAQ,qBAAqB,CAAA;AAClE,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,kDAAA,EAAoD,IAAA,CAAK,OAAA,CAAQ,qBAAqB,CAAA;AAAA,MACpG;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AAAA,IACzC;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,YAAA,EAAc;AAC7B,MAAA,IAAA,CAAK,IAAA,CAAK,iBAAA,EAAmB,IAAA,CAAK,OAAA,CAAQ,YAAY,CAAA;AAAA,IACxD;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAAA,IACrB;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAA,GAA8B;AACpC,IAAA,MAAM,GAAA,GAAyB;AAAA,MAC7B,GAAG,OAAA,CAAQ,GAAA;AAAA,MACX,GAAG,KAAK,OAAA,CAAQ;AAAA,KAClB;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AAGvB,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,yBAAA,KAA8B,MAAA;AAEpE,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,qDAAqD,IAAA,CAAK,OAAA,CAAQ,OAAO,SAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA;AACpG,QAAA,OAAA,CAAQ,GAAA,CAAI,8DAAA,EAAgE,IAAA,CAAK,OAAA,CAAQ,KAAK,yBAAyB,CAAA;AACvH,QAAA,OAAA,CAAQ,GAAA,CAAI,kDAAkD,WAAW,CAAA;AAAA,MAC3E;AAEA,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,GAAA,CAAI,cAAA,GAAiB,KAAK,OAAA,CAAQ,MAAA;AAClC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,IAAI,wEAAwE,CAAA;AAAA,QACtF;AAAA,MACF,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,cAAA,GAAiB,KAAK,OAAA,CAAQ,MAAA;AAClC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,IAAI,wEAAwE,CAAA;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,GAAA,CAAI,iEAAA,EAAmE,CAAC,CAAC,IAAI,cAAc,CAAA;AACnG,MAAA,OAAA,CAAQ,GAAA,CAAI,iEAAA,EAAmE,CAAC,CAAC,IAAI,cAAc,CAAA;AACnG,MAAA,OAAA,CAAQ,GAAA,CAAI,wEAAA,EAA0E,GAAA,CAAI,yBAAyB,CAAA;AAAA,IACrH;AAEA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,OAAA,EAAiC;AACpD,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACrB,MAAA,MAAM,IAAI,eAAe,4BAA4B,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AACnC,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,IAAI,gDAAA,EAAkD,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,IACtF;AAEA,IAAA,MAAM,UAAU,IAAA,CAAK,WAAA,CAAY,MAAM,IAAA,GAAO,IAAA,EAAM,CAAC,KAAA,KAAU;AAC7D,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,OAAA,CAAQ,KAAA,CAAM,qCAAqC,KAAK,CAAA;AAAA,MAC1D,CAAA,MAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO;AAC7B,QAAA,OAAA,CAAQ,IAAI,+DAA+D,CAAA;AAAA,MAC7E;AAAA,IACF,CAAC,CAAA;AAED,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,IAAI,qCAAA,EAAuC,OAAA,EAAS,kBAAA,EAAoB,IAAA,CAAK,YAAY,QAAQ,CAAA;AAAA,IAC3G;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,CAAC,KAAK,iBAAA,EAAmB;AAC3B,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,iBAAA,CAAkB,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,KAAS;AAC1C,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAChC,QAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AAAA,MACxB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,8CAA8C,OAAO,CAAA;AACnE,QAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAAA,MACpD;AAAA,IACF,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,iBAAA,CAAkB,EAAA,CAAG,OAAA,EAAS,MAAM;AAEvC,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,IAAI,gDAAgD,CAAA;AAAA,MAC9D;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,KAAA,EAA8B;AAEhD,IAAA,IAAI,MAAM,IAAA,KAAA,MAAA,aAAmC;AAC3C,MAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAGjB,MAAA,IAAI,KAAK,WAAA,EAAa;AACpB,QAAA,YAAA,CAAa,KAAK,WAAW,CAAA;AAC7B,QAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,MACrB;AAEA,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,SAAS,CAAA;AAAA,IACnC;AAGA,IAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAA,GAA6B;AACzC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,GAAA;AAE5C,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AAEtC,MAAA,IAAI,KAAK,SAAA,EAAW;AAClB,QAAA,OAAA,EAAQ;AACR,QAAA;AAAA,MACF;AAGA,MAAA,IAAA,CAAK,WAAA,GAAc,WAAW,MAAM;AAClC,QAAA,MAAA,CAAO,IAAI,cAAA,CAAe,wBAAA,EAA0B,QAAW,EAAE,OAAA,EAAS,CAAC,CAAA;AAAA,MAC7E,GAAG,OAAO,CAAA;AAGV,MAAA,IAAA,CAAK,IAAA,CAAK,SAAS,MAAM;AACvB,QAAA,OAAA,EAAQ;AAAA,MACV,CAAC,CAAA;AAGD,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,CAAC,KAAA,KAAU;AAC5B,QAAA,MAAA,CAAO,KAAK,CAAA;AAAA,MACd,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,CAAkB,MAAqB,MAAA,EAAqC;AAClF,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,GAAA,CAAI,sCAAA,EAAwC,EAAE,IAAA,EAAM,QAAQ,CAAA;AAAA,IACtE;AAEA,IAAA,IAAI,IAAA,KAAS,CAAA,IAAK,IAAA,KAAS,IAAA,EAAM;AAC/B,MAAA,IAAA,CAAK,MAAA,GAAA,OAAA;AACL,MAAA,IAAA,CAAK,IAAA,CAAK,SAAS,IAAI,cAAA,CAAe,4BAA4B,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,CAAA;AAAA,IACjF,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,GAAA,WAAA;AAAA,IACP;AAEA,IAAA,IAAA,CAAK,IAAA,CAAK,WAAW,IAAI,CAAA;AAGzB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAC7B,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,KAAA,EAAoB;AAC7C,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,KAAK,CAAA;AAC1D,IAAA,IAAA,CAAK,MAAA,GAAA,OAAA;AACL,IAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EAC1B;AACF;AC1hBO,SAAS,aAAA,CAAc,GAAA,GAAc,OAAA,CAAQ,GAAA,EAAI,EAAW;AAEjE,EAAA,IAAI,OAAA,CAAQ,IAAI,eAAA,EAAiB;AAC/B,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,eAAA;AAC5B,IAAA,IAAO,GAAA,CAAA,UAAA,CAAW,OAAO,CAAA,EAAG;AAC1B,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,MAAM,YAAiB,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,gBAAgB,SAAA,EAAW,YAAA,EAAc,UAAU,WAAW,CAAA;AAC/F,EAAA,IAAO,GAAA,CAAA,UAAA,CAAW,SAAS,CAAA,EAAG;AAC5B,IAAA,OAAO,SAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,GAAa,GAAA;AACjB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,UAAA,GAAkB,KAAA,CAAA,IAAA;AAAA,MACtB,UAAA;AAAA,MACA,cAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAO,GAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7B,MAAA,OAAO,UAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAA,GAAiB,cAAQ,UAAU,CAAA;AACzC,IAAA,IAAI,cAAc,UAAA,EAAY;AAC9B,IAAA,UAAA,GAAa,SAAA;AAAA,EACf;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR;AAAA,GACF;AACF;AAQO,SAAS,eAAe,MAAA,EAA0B;AACvD,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,MAAA,GAAS,QAAQ,GAAA,CAAI,cAAA;AAC3B,IAAA,OAAO,CAAC,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,GAAS,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,OAAO,MAAA,GAAS,CAAA;AACzB;AASO,SAAS,UAAU,MAAA,EAAyB;AACjD,EAAA,MAAM,GAAA,GAAM,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,cAAA;AAClC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAQO,SAAS,cAAc,KAAA,EAAwB;AACpD,EAAA,MAAM,YAAA,GAAe,sBAAA;AACrB,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,YAAA;AAAA,EACT;AAGA,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA,EAAG;AAChC,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,qBAAA,EAAwB,KAAK,CAAA,+BAAA,CAAiC,CAAA;AAAA,EAC7E;AAEA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,eAAe,EAAA,EAAoB;AACjD,EAAA,IAAI,KAAK,GAAA,EAAM;AACb,IAAA,OAAO,GAAG,EAAE,CAAA,EAAA,CAAA;AAAA,EACd;AACA,EAAA,IAAI,KAAK,GAAA,EAAO;AACd,IAAA,OAAO,CAAA,EAAA,CAAI,EAAA,GAAK,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,EAClC;AACA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAK,CAAA;AACrC,EAAA,MAAM,OAAA,GAAA,CAAY,EAAA,GAAK,GAAA,GAAS,GAAA,EAAM,QAAQ,CAAC,CAAA;AAC/C,EAAA,OAAO,CAAA,EAAG,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,CAAA;AAC/B;AAQO,SAAS,aAAa,MAAA,EAAwB;AACnD,EAAA,OAAO,OAAO,cAAA,EAAe;AAC/B","file":"index.js","sourcesContent":["/**\n * Type definitions for Gemini CLI SDK\n *\n * Based on Gemini CLI v0.21.0+ interface specification\n */\n\n/**\n * Gemini CLI configuration options\n */\nexport interface GeminiOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request */\n TOOL_USE = 'tool_use',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event\n */\nexport interface ToolUseEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_USE;\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n value: ThoughtSummary;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n };\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Hook configuration types (from Gemini CLI)\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\nexport interface HookDefinition {\n matcher?: string;\n sequential?: boolean;\n hooks: HookConfig[];\n}\n\nexport interface HooksConfiguration {\n BeforeTool?: HookDefinition[];\n AfterTool?: HookDefinition[];\n BeforeAgent?: HookDefinition[];\n AfterAgent?: HookDefinition[];\n BeforeModel?: HookDefinition[];\n AfterModel?: HookDefinition[];\n BeforeToolSelection?: HookDefinition[];\n Notification?: HookDefinition[];\n SessionStart?: HookDefinition[];\n SessionEnd?: HookDefinition[];\n PreCompress?: HookDefinition[];\n disabled?: string[];\n}\n\n/**\n * Options for GeminiStreamClient\n */\nexport interface GeminiStreamOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Session ID for this client instance\n * Each client manages one session\n */\n sessionId: string;\n\n /**\n * Workspace ID (optional, for tracking)\n */\n workspaceId?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Approval mode for tool execution\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n\n /**\n * Hooks configuration\n * Passed to Gemini CLI via temporary settings.json\n */\n hooks?: HooksConfiguration;\n\n /**\n * Resume from a previous session file path\n * If provided, Gemini CLI will load the session history using --resume flag\n * @example '/path/to/session-2025-01-01T12-00-abc123.json'\n */\n resumeSessionFilePath?: string;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn('node', [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n private tempSettingsPath: string | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Create temporary settings.json if hooks are configured\n if (this.options.hooks) {\n await this.createTempSettings();\n }\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Spawn process\n this.process = spawn('node', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n */\n async sendMessage(content: string): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.USER,\n content,\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Send an interrupt control command\n */\n async interrupt(): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'interrupt',\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n\n // Clean up temporary settings file\n if (this.tempSettingsPath) {\n try {\n fs.unlinkSync(this.tempSettingsPath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Cleaned up temp settings:', this.tempSettingsPath);\n }\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to clean up temp settings:', error);\n }\n this.tempSettingsPath = null;\n }\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Create temporary settings.json for hooks configuration\n */\n private async createTempSettings(): Promise<void> {\n const tempDir = os.tmpdir();\n this.tempSettingsPath = path.join(tempDir, `gemini-settings-${this.options.sessionId}.json`);\n\n const settings = {\n tools: {\n enableHooks: true,\n },\n hooks: this.options.hooks,\n };\n\n try {\n fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Created temp settings:', this.tempSettingsPath);\n console.log('[GeminiStreamClient] Settings content:', JSON.stringify(settings, null, 2));\n }\n } catch (error) {\n throw new GeminiSDKError(`Failed to create temp settings file: ${error}`);\n }\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Settings file (for hooks configuration)\n if (this.tempSettingsPath) {\n args.push('--settings-file', this.tempSettingsPath);\n }\n\n // Resume from previous session file\n if (this.options.resumeSessionFilePath) {\n args.push('--resume-from-file', this.options.resumeSessionFilePath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Resuming from session file:', this.options.resumeSessionFilePath);\n }\n }\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
package/package.json
CHANGED