@ketd/gemini-cli-sdk 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +310 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +212 -1
- package/dist/index.d.ts +212 -1
- package/dist/index.js +309 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -43,6 +43,11 @@ var GeminiSDKError = class _GeminiSDKError extends Error {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
|
+
var JsonInputMessageType = /* @__PURE__ */ ((JsonInputMessageType2) => {
|
|
47
|
+
JsonInputMessageType2["USER"] = "user";
|
|
48
|
+
JsonInputMessageType2["CONTROL"] = "control";
|
|
49
|
+
return JsonInputMessageType2;
|
|
50
|
+
})(JsonInputMessageType || {});
|
|
46
51
|
|
|
47
52
|
// src/query.ts
|
|
48
53
|
function buildCliArgs(options, prompt) {
|
|
@@ -362,6 +367,309 @@ var GeminiClient = class extends EventEmitter {
|
|
|
362
367
|
return { ...this.options };
|
|
363
368
|
}
|
|
364
369
|
};
|
|
370
|
+
var GeminiStreamClient = class extends EventEmitter {
|
|
371
|
+
constructor(options) {
|
|
372
|
+
super();
|
|
373
|
+
this.options = options;
|
|
374
|
+
if (!options.pathToGeminiCLI) {
|
|
375
|
+
throw new GeminiSDKError("pathToGeminiCLI is required");
|
|
376
|
+
}
|
|
377
|
+
if (!options.sessionId) {
|
|
378
|
+
throw new GeminiSDKError("sessionId is required");
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
process = null;
|
|
382
|
+
stdinStream = null;
|
|
383
|
+
readlineInterface = null;
|
|
384
|
+
status = "idle" /* IDLE */;
|
|
385
|
+
initEvent = null;
|
|
386
|
+
initTimeout = null;
|
|
387
|
+
/**
|
|
388
|
+
* Start the Gemini CLI process
|
|
389
|
+
*/
|
|
390
|
+
async start() {
|
|
391
|
+
if (this.process) {
|
|
392
|
+
throw new GeminiSDKError("Process already started");
|
|
393
|
+
}
|
|
394
|
+
this.status = "running" /* RUNNING */;
|
|
395
|
+
const args = this.buildCommand();
|
|
396
|
+
const env = this.buildEnv();
|
|
397
|
+
this.process = spawn("node", args, {
|
|
398
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
399
|
+
cwd: this.options.cwd || process.cwd(),
|
|
400
|
+
env
|
|
401
|
+
});
|
|
402
|
+
this.process.on("exit", (code, signal) => {
|
|
403
|
+
this.handleProcessExit(code, signal);
|
|
404
|
+
});
|
|
405
|
+
this.process.on("error", (error) => {
|
|
406
|
+
this.handleProcessError(error);
|
|
407
|
+
});
|
|
408
|
+
if (this.process.stdin) {
|
|
409
|
+
this.stdinStream = this.process.stdin;
|
|
410
|
+
this.stdinStream.setDefaultEncoding("utf-8");
|
|
411
|
+
} else {
|
|
412
|
+
throw new GeminiSDKError("Failed to get stdin stream");
|
|
413
|
+
}
|
|
414
|
+
if (this.process.stdout) {
|
|
415
|
+
this.readlineInterface = readline.createInterface({
|
|
416
|
+
input: this.process.stdout,
|
|
417
|
+
terminal: false
|
|
418
|
+
// CRITICAL: Non-terminal mode for JSONL
|
|
419
|
+
});
|
|
420
|
+
this.startReadLoop();
|
|
421
|
+
} else {
|
|
422
|
+
throw new GeminiSDKError("Failed to get stdout stream");
|
|
423
|
+
}
|
|
424
|
+
if (this.process.stderr && this.options.debug) {
|
|
425
|
+
this.process.stderr.on("data", (chunk) => {
|
|
426
|
+
console.error("[GeminiStreamClient] stderr:", chunk.toString());
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
this.emit("started");
|
|
430
|
+
await this.waitForInit();
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Send a user message to the CLI
|
|
434
|
+
*/
|
|
435
|
+
async sendMessage(content) {
|
|
436
|
+
if (!this.isReady()) {
|
|
437
|
+
throw new GeminiSDKError("Client not ready. Call start() first.");
|
|
438
|
+
}
|
|
439
|
+
const message = {
|
|
440
|
+
type: "user" /* USER */,
|
|
441
|
+
content,
|
|
442
|
+
session_id: this.options.sessionId
|
|
443
|
+
};
|
|
444
|
+
this.writeMessage(message);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Send an interrupt control command
|
|
448
|
+
*/
|
|
449
|
+
async interrupt() {
|
|
450
|
+
if (!this.isReady()) {
|
|
451
|
+
throw new GeminiSDKError("Client not ready. Call start() first.");
|
|
452
|
+
}
|
|
453
|
+
const message = {
|
|
454
|
+
type: "control" /* CONTROL */,
|
|
455
|
+
control: {
|
|
456
|
+
subtype: "interrupt"
|
|
457
|
+
},
|
|
458
|
+
session_id: this.options.sessionId
|
|
459
|
+
};
|
|
460
|
+
this.writeMessage(message);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Stop the CLI process
|
|
464
|
+
*/
|
|
465
|
+
async stop(timeout = 5e3) {
|
|
466
|
+
if (!this.process) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
if (this.initTimeout) {
|
|
470
|
+
clearTimeout(this.initTimeout);
|
|
471
|
+
this.initTimeout = null;
|
|
472
|
+
}
|
|
473
|
+
if (this.stdinStream) {
|
|
474
|
+
this.stdinStream.end();
|
|
475
|
+
this.stdinStream = null;
|
|
476
|
+
}
|
|
477
|
+
if (this.readlineInterface) {
|
|
478
|
+
this.readlineInterface.close();
|
|
479
|
+
this.readlineInterface = null;
|
|
480
|
+
}
|
|
481
|
+
await Promise.race([
|
|
482
|
+
new Promise((resolve) => {
|
|
483
|
+
if (this.process) {
|
|
484
|
+
this.process.once("exit", () => resolve());
|
|
485
|
+
} else {
|
|
486
|
+
resolve();
|
|
487
|
+
}
|
|
488
|
+
}),
|
|
489
|
+
new Promise((resolve) => setTimeout(resolve, timeout))
|
|
490
|
+
]);
|
|
491
|
+
if (this.process && !this.process.killed) {
|
|
492
|
+
this.process.kill("SIGTERM");
|
|
493
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
494
|
+
if (this.process && !this.process.killed) {
|
|
495
|
+
this.process.kill("SIGKILL");
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
this.process = null;
|
|
499
|
+
this.status = "completed" /* COMPLETED */;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Check if client is ready to send messages
|
|
503
|
+
*/
|
|
504
|
+
isReady() {
|
|
505
|
+
return this.status === "running" /* RUNNING */ && this.initEvent !== null;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Get current status
|
|
509
|
+
*/
|
|
510
|
+
getStatus() {
|
|
511
|
+
return this.status;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Get init event (contains session_id, model, etc.)
|
|
515
|
+
*/
|
|
516
|
+
getInitEvent() {
|
|
517
|
+
return this.initEvent;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Get process PID
|
|
521
|
+
*/
|
|
522
|
+
getPid() {
|
|
523
|
+
return this.process?.pid;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Build CLI command arguments
|
|
527
|
+
*/
|
|
528
|
+
buildCommand() {
|
|
529
|
+
const args = [
|
|
530
|
+
this.options.pathToGeminiCLI,
|
|
531
|
+
"--stream-json-input",
|
|
532
|
+
// ← New flag we'll add to CLI
|
|
533
|
+
"--output-format",
|
|
534
|
+
"stream-json"
|
|
535
|
+
];
|
|
536
|
+
if (this.options.model) {
|
|
537
|
+
args.push("--model", this.options.model);
|
|
538
|
+
}
|
|
539
|
+
if (this.options.approvalMode) {
|
|
540
|
+
args.push("--approval-mode", this.options.approvalMode);
|
|
541
|
+
}
|
|
542
|
+
if (this.options.debug) {
|
|
543
|
+
args.push("--debug");
|
|
544
|
+
}
|
|
545
|
+
return args;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Build environment variables
|
|
549
|
+
*/
|
|
550
|
+
buildEnv() {
|
|
551
|
+
const env = {
|
|
552
|
+
...process.env,
|
|
553
|
+
...this.options.env
|
|
554
|
+
};
|
|
555
|
+
if (this.options.apiKey) {
|
|
556
|
+
env.GEMINI_API_KEY = this.options.apiKey;
|
|
557
|
+
}
|
|
558
|
+
return env;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Write a JSON message to stdin
|
|
562
|
+
*/
|
|
563
|
+
writeMessage(message) {
|
|
564
|
+
if (!this.stdinStream) {
|
|
565
|
+
throw new GeminiSDKError("stdin stream not available");
|
|
566
|
+
}
|
|
567
|
+
const json = JSON.stringify(message);
|
|
568
|
+
if (this.options.debug) {
|
|
569
|
+
console.log("[GeminiStreamClient] Writing message to stdin:", json.substring(0, 100));
|
|
570
|
+
}
|
|
571
|
+
const success = this.stdinStream.write(json + "\n", (error) => {
|
|
572
|
+
if (error) {
|
|
573
|
+
console.error("[GeminiStreamClient] Write error:", error);
|
|
574
|
+
} else if (this.options.debug) {
|
|
575
|
+
console.log("[GeminiStreamClient] Write callback: message flushed to stdin");
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
if (this.options.debug) {
|
|
579
|
+
console.log("[GeminiStreamClient] Write success:", success, "Stream writable:", this.stdinStream.writable);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Start reading JSONL events from stdout
|
|
584
|
+
*/
|
|
585
|
+
startReadLoop() {
|
|
586
|
+
if (!this.readlineInterface) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
this.readlineInterface.on("line", (line) => {
|
|
590
|
+
const trimmed = line.trim();
|
|
591
|
+
if (!trimmed) {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
try {
|
|
595
|
+
const event = JSON.parse(trimmed);
|
|
596
|
+
this.handleEvent(event);
|
|
597
|
+
} catch (error) {
|
|
598
|
+
console.error("[GeminiStreamClient] Failed to parse JSON:", trimmed);
|
|
599
|
+
console.error("[GeminiStreamClient] Error:", error);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
this.readlineInterface.on("close", () => {
|
|
603
|
+
if (this.options.debug) {
|
|
604
|
+
console.log("[GeminiStreamClient] readline interface closed");
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Handle a JSON stream event
|
|
610
|
+
*/
|
|
611
|
+
handleEvent(event) {
|
|
612
|
+
if (event.type === "init" /* INIT */) {
|
|
613
|
+
this.initEvent = event;
|
|
614
|
+
if (this.initTimeout) {
|
|
615
|
+
clearTimeout(this.initTimeout);
|
|
616
|
+
this.initTimeout = null;
|
|
617
|
+
}
|
|
618
|
+
this.emit("ready", this.initEvent);
|
|
619
|
+
}
|
|
620
|
+
this.emit("event", event);
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Wait for INIT event
|
|
624
|
+
*/
|
|
625
|
+
async waitForInit() {
|
|
626
|
+
const timeout = this.options.initTimeout || 3e4;
|
|
627
|
+
return new Promise((resolve, reject) => {
|
|
628
|
+
if (this.initEvent) {
|
|
629
|
+
resolve();
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
this.initTimeout = setTimeout(() => {
|
|
633
|
+
reject(new GeminiSDKError("Initialization timeout", void 0, { timeout }));
|
|
634
|
+
}, timeout);
|
|
635
|
+
this.once("ready", () => {
|
|
636
|
+
resolve();
|
|
637
|
+
});
|
|
638
|
+
this.once("error", (error) => {
|
|
639
|
+
reject(error);
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Handle process exit
|
|
645
|
+
*/
|
|
646
|
+
handleProcessExit(code, signal) {
|
|
647
|
+
if (this.options.debug) {
|
|
648
|
+
console.log("[GeminiStreamClient] Process exited:", { code, signal });
|
|
649
|
+
}
|
|
650
|
+
if (code !== 0 && code !== null) {
|
|
651
|
+
this.status = "error" /* ERROR */;
|
|
652
|
+
this.emit("error", new GeminiSDKError(`Process exited with code ${code}`, code));
|
|
653
|
+
} else {
|
|
654
|
+
this.status = "completed" /* COMPLETED */;
|
|
655
|
+
}
|
|
656
|
+
this.emit("stopped", code);
|
|
657
|
+
this.process = null;
|
|
658
|
+
this.stdinStream = null;
|
|
659
|
+
if (this.readlineInterface) {
|
|
660
|
+
this.readlineInterface.close();
|
|
661
|
+
this.readlineInterface = null;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Handle process error
|
|
666
|
+
*/
|
|
667
|
+
handleProcessError(error) {
|
|
668
|
+
console.error("[GeminiStreamClient] Process error:", error);
|
|
669
|
+
this.status = "error" /* ERROR */;
|
|
670
|
+
this.emit("error", error);
|
|
671
|
+
}
|
|
672
|
+
};
|
|
365
673
|
function findGeminiCLI(cwd = process.cwd()) {
|
|
366
674
|
if (process.env.GEMINI_CLI_PATH) {
|
|
367
675
|
const envPath = process.env.GEMINI_CLI_PATH;
|
|
@@ -435,6 +743,6 @@ function formatTokens(tokens) {
|
|
|
435
743
|
return tokens.toLocaleString();
|
|
436
744
|
}
|
|
437
745
|
|
|
438
|
-
export { ExitCode, GeminiClient, GeminiSDKError, JsonStreamEventType, ProcessStatus, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
|
|
746
|
+
export { ExitCode, GeminiClient, GeminiSDKError, GeminiStreamClient, JsonInputMessageType, JsonStreamEventType, ProcessStatus, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
|
|
439
747
|
//# sourceMappingURL=index.js.map
|
|
440
748
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus"],"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 */\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\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/reasoning event\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n subject: string;\n description?: 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 * 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\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 * 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 * 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"],"mappings":";;;;;;;;;AAwIO,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;AApBC,EAAA,OAAAA,oBAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;AAoIL,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;;;AC3VZ,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;ACtKO,IAAM,kBAAA,GAAN,cAAiCC,YAAAA,CAAa;AAAA,EAQnD,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,EAjBQ,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;AAAA;AAAA;AAAA,EAiB7C,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,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,OAAA,CAAQ,MAAA,IAAU,IAAA,CAAK,QAAQ,KAAA,EAAO;AAC7C,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAU;AACxC,QAAA,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,KAAA,CAAM,QAAA,EAAU,CAAA;AAAA,MAChE,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;AAAA,EACP;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,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,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;AACvB,MAAA,GAAA,CAAI,cAAA,GAAiB,KAAK,OAAA,CAAQ,MAAA;AAAA,IACpC;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;ACjcO,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,EAAA,CAAA,UAAA,CAAW,OAAO,CAAA,EAAG;AAC1B,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,MAAM,YAAiB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,gBAAgB,SAAA,EAAW,YAAA,EAAc,UAAU,WAAW,CAAA;AAC/F,EAAA,IAAO,EAAA,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,IAAA,CAAA,IAAA;AAAA,MACtB,UAAA;AAAA,MACA,cAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAO,EAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7B,MAAA,OAAO,UAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAA,GAAiB,aAAQ,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 */\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\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/reasoning event\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n subject: string;\n description?: 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 * 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\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 (for debugging)\n if (this.process.stderr && this.options.debug) {\n this.process.stderr.on('data', (chunk) => {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\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 env.GEMINI_API_KEY = this.options.apiKey;\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