@ketd/gemini-cli-sdk 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +40 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -5
- package/dist/index.d.ts +87 -5
- package/dist/index.js +40 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -422,7 +422,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
422
422
|
throw new GeminiSDKError("Process already started");
|
|
423
423
|
}
|
|
424
424
|
this.status = "running" /* RUNNING */;
|
|
425
|
-
if (this.options.hooks) {
|
|
425
|
+
if (this.options.hooks || this.options.mcpServers) {
|
|
426
426
|
await this.createTempSettings();
|
|
427
427
|
}
|
|
428
428
|
const args = this.buildCommand();
|
|
@@ -498,6 +498,34 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
498
498
|
};
|
|
499
499
|
this.writeMessage(message);
|
|
500
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* Truncate chat history from a specific index
|
|
503
|
+
*
|
|
504
|
+
* This sends a control message to the CLI to:
|
|
505
|
+
* 1. Truncate in-memory history (via GeminiChat.setHistory())
|
|
506
|
+
* 2. Sync to session.json file (via ChatRecordingService)
|
|
507
|
+
*
|
|
508
|
+
* Used for edit/retry functionality where subsequent messages need to be discarded.
|
|
509
|
+
*
|
|
510
|
+
* @param fromIndex - Index from which to truncate (0-based, inclusive)
|
|
511
|
+
*/
|
|
512
|
+
async truncateHistory(fromIndex) {
|
|
513
|
+
if (!this.isReady()) {
|
|
514
|
+
throw new GeminiSDKError("Client not ready. Call start() first.");
|
|
515
|
+
}
|
|
516
|
+
if (fromIndex < 0) {
|
|
517
|
+
throw new GeminiSDKError("fromIndex must be non-negative");
|
|
518
|
+
}
|
|
519
|
+
const message = {
|
|
520
|
+
type: "control" /* CONTROL */,
|
|
521
|
+
control: {
|
|
522
|
+
subtype: "truncate_history",
|
|
523
|
+
fromIndex
|
|
524
|
+
},
|
|
525
|
+
session_id: this.options.sessionId
|
|
526
|
+
};
|
|
527
|
+
this.writeMessage(message);
|
|
528
|
+
}
|
|
501
529
|
/**
|
|
502
530
|
* Stop the CLI process
|
|
503
531
|
*/
|
|
@@ -573,7 +601,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
573
601
|
return this.process?.pid;
|
|
574
602
|
}
|
|
575
603
|
/**
|
|
576
|
-
* Create settings.json in GEMINI_CONFIG_DIR for hooks configuration
|
|
604
|
+
* Create settings.json in GEMINI_CONFIG_DIR for hooks and MCP servers configuration
|
|
577
605
|
*
|
|
578
606
|
* Note: Gemini CLI does not support --settings-file parameter.
|
|
579
607
|
* Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
|
|
@@ -583,7 +611,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
583
611
|
const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;
|
|
584
612
|
if (!geminiConfigDir) {
|
|
585
613
|
throw new GeminiSDKError(
|
|
586
|
-
"GEMINI_CONFIG_DIR is required in options.env when using hooks. Please set options.env.GEMINI_CONFIG_DIR to a directory path."
|
|
614
|
+
"GEMINI_CONFIG_DIR is required in options.env when using hooks or mcpServers. Please set options.env.GEMINI_CONFIG_DIR to a directory path."
|
|
587
615
|
);
|
|
588
616
|
}
|
|
589
617
|
if (!fs__namespace.existsSync(geminiConfigDir)) {
|
|
@@ -593,12 +621,16 @@ var GeminiStreamClient = class extends events.EventEmitter {
|
|
|
593
621
|
}
|
|
594
622
|
}
|
|
595
623
|
this.tempSettingsPath = path2__namespace.join(geminiConfigDir, "settings.json");
|
|
596
|
-
const settings = {
|
|
597
|
-
|
|
624
|
+
const settings = {};
|
|
625
|
+
if (this.options.hooks) {
|
|
626
|
+
settings.tools = {
|
|
598
627
|
enableHooks: true
|
|
599
|
-
}
|
|
600
|
-
hooks
|
|
601
|
-
}
|
|
628
|
+
};
|
|
629
|
+
settings.hooks = this.options.hooks;
|
|
630
|
+
}
|
|
631
|
+
if (this.options.mcpServers) {
|
|
632
|
+
settings.mcpServers = this.options.mcpServers;
|
|
633
|
+
}
|
|
602
634
|
try {
|
|
603
635
|
fs__namespace.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
604
636
|
if (this.options.debug) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","spawn","readline","EventEmitter","readline2","fs","path","fs2","path2"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkJO,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,mBAAA,CAAA,GAAoB,mBAAA;AAGpB,EAAAA,qBAAA,aAAA,CAAA,GAAc,aAAA;AAGd,EAAAA,qBAAA,SAAA,CAAA,GAAU,SAAA;AAGV,EAAAA,qBAAA,OAAA,CAAA,GAAQ,OAAA;AAGR,EAAAA,qBAAA,QAAA,CAAA,GAAS,QAAA;AAIT,EAAAA,qBAAA,SAAA,CAAA,GAAU,SAAA;AAGV,EAAAA,qBAAA,UAAA,CAAA,GAAW,UAAA;AAGX,EAAAA,qBAAA,YAAA,CAAA,GAAa,YAAA;AAjCH,EAAA,OAAAA,oBAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;AAwNL,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;;;ACzbZ,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,MAAM,cAAA,GAAiB,QAAQ,UAAA,IAAc,MAAA;AAG7C,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgBC,oBAAM,cAAA,EAAgB,CAAC,QAAQ,eAAA,EAAiB,GAAG,IAAI,CAAA,EAAG;AAAA,MACxE,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,KAAcC,mBAAA,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;ACnOO,IAAM,YAAA,GAAN,cAA2BC,mBAAA,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;ACpKO,IAAM,kBAAA,GAAN,cAAiCA,mBAAAA,CAAa;AAAA,EASnD,YAAoB,OAAA,EAA8B;AAChD,IAAA,KAAA,EAAM;AADY,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAIlB,IAAA,IAAI,CAAC,QAAQ,eAAA,EAAiB;AAC5B,MAAA,MAAM,IAAI,eAAe,6BAA6B,CAAA;AAAA,IACxD;AACA,IAAA,IAAI,CAAC,QAAQ,SAAA,EAAW;AACtB,MAAA,MAAM,IAAI,eAAe,uBAAuB,CAAA;AAAA,IAClD;AAAA,EACF;AAAA,EAlBQ,OAAA,GAA+B,IAAA;AAAA,EAC/B,WAAA,GAA+B,IAAA;AAAA,EAC/B,iBAAA,GAA+C,IAAA;AAAA,EAC/C,MAAA,GAAA,MAAA;AAAA,EACA,SAAA,GAA8B,IAAA;AAAA,EAC9B,WAAA,GAAqC,IAAA;AAAA,EACrC,gBAAA,GAAkC,IAAA;AAAA;AAAA;AAAA;AAAA,EAiB1C,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,MAAM,IAAI,eAAe,yBAAyB,CAAA;AAAA,IACpD;AAEA,IAAA,IAAA,CAAK,MAAA,GAAA,SAAA;AAGL,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,MAAM,KAAK,kBAAA,EAAmB;AAAA,IAChC;AAGA,IAAA,MAAM,IAAA,GAAO,KAAK,YAAA,EAAa;AAG/B,IAAA,MAAM,GAAA,GAAM,KAAK,QAAA,EAAS;AAG1B,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,UAAA,IAAc,MAAA;AAGlD,IAAA,IAAA,CAAK,OAAA,GAAUF,mBAAAA,CAAM,cAAA,EAAgB,IAAA,EAAM;AAAA,MACzC,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,oBAA6BG,mBAAA,CAAA,eAAA,CAAgB;AAAA,QAChD,KAAA,EAAO,KAAK,OAAA,CAAQ,MAAA;AAAA,QACpB,QAAA,EAAU;AAAA;AAAA,OACX,CAAA;AAGD,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,eAAe,6BAA6B,CAAA;AAAA,IACxD;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAU;AAExC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,KAAA,CAAM,QAAA,EAAU,CAAA;AAAA,QAChE;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAGnB,IAAA,MAAM,KAAK,WAAA,EAAY;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAA,CAAY,OAAA,EAAiB,0BAAA,EAAoD;AACrF,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,SAAA;AAAA,MACzB,4BAAA,EAA8B;AAAA,KAChC;AAEA,IAAA,IAAA,CAAK,aAAa,OAAO,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,GAA2B;AAC/B,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAQ,EAAG;AACnB,MAAA,MAAM,IAAI,eAAe,uCAAuC,CAAA;AAAA,IAClE;AAEA,IAAA,MAAM,OAAA,GAA4B;AAAA,MAChC,IAAA,EAAA,SAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,OAAA,EAAS;AAAA,OACX;AAAA,MACA,UAAA,EAAY,KAAK,OAAA,CAAQ;AAAA,KAC3B;AAEA,IAAA,IAAA,CAAK,aAAa,OAAO,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAK,OAAA,GAAkB,GAAA,EAAqB;AAChD,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,YAAA,CAAa,KAAK,WAAW,CAAA;AAC7B,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAGA,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,YAAY,GAAA,EAAI;AACrB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAGA,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAC7B,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B;AAGA,IAAA,MAAM,QAAQ,IAAA,CAAK;AAAA,MACjB,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AAC7B,QAAA,IAAI,KAAK,OAAA,EAAS;AAChB,UAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,MAAA,EAAQ,MAAM,SAAS,CAAA;AAAA,QAC3C,CAAA,MAAO;AACL,UAAA,OAAA,EAAQ;AAAA,QACV;AAAA,MACF,CAAC,CAAA;AAAA,MACD,IAAI,OAAA,CAAc,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,OAAO,CAAC;AAAA,KAC5D,CAAA;AAGD,IAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACxC,MAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,SAAS,CAAA;AAG3B,MAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,GAAI,CAAC,CAAA;AAGxD,MAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACxC,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,SAAS,CAAA;AAAA,MAC7B;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,MAAA,GAAA,WAAA;AAGL,IAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,MAAA,IAAI;AACF,QAAGC,aAAA,CAAA,UAAA,CAAW,KAAK,gBAAgB,CAAA;AACnC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,GAAA,CAAI,gDAAA,EAAkD,IAAA,CAAK,gBAAgB,CAAA;AAAA,QACrF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,0DAA0D,KAAK,CAAA;AAAA,MAC/E;AACA,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAmB;AACjB,IAAA,OAAO,IAAA,CAAK,MAAA,KAAA,SAAA,kBAAoC,IAAA,CAAK,SAAA,KAAc,IAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA2B;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAA6B;AAC3B,IAAA,OAAO,KAAK,OAAA,EAAS,GAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,kBAAA,GAAoC;AAEhD,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,iBAAA;AAE1C,IAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,MAAA,MAAM,IAAI,cAAA;AAAA,QACR;AAAA,OAEF;AAAA,IACF;AAGA,IAAA,IAAI,CAAIA,aAAA,CAAA,UAAA,CAAW,eAAe,CAAA,EAAG;AACnC,MAAGA,aAAA,CAAA,SAAA,CAAU,eAAA,EAAiB,EAAE,SAAA,EAAW,MAAM,CAAA;AACjD,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,kDAAkD,eAAe,CAAA;AAAA,MAC/E;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,gBAAA,GAAwBC,gBAAA,CAAA,IAAA,CAAK,eAAA,EAAiB,eAAe,CAAA;AAElE,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,KAAA,EAAO;AAAA,QACL,WAAA,EAAa;AAAA,OACf;AAAA,MACA,KAAA,EAAO,KAAK,OAAA,CAAQ;AAAA,KACtB;AAEA,IAAA,IAAI;AACF,MAAGD,aAAA,CAAA,aAAA,CAAc,KAAK,gBAAA,EAAkB,IAAA,CAAK,UAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA,EAAG,OAAO,CAAA;AAClF,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,yCAAA,EAA2C,IAAA,CAAK,gBAAgB,CAAA;AAC5E,QAAA,OAAA,CAAQ,IAAI,wCAAA,EAA0C,IAAA,CAAK,UAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,MACzF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,cAAA,CAAe,CAAA,+BAAA,EAAkC,KAAK,CAAA,CAAE,CAAA;AAAA,IACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAA,GAAyB;AAC/B,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,KAAK,OAAA,CAAQ,eAAA;AAAA,MACb,qBAAA;AAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACF;AAMA,IAAA,IAAI,IAAA,CAAK,QAAQ,qBAAA,EAAuB;AACtC,MAAA,IAAA,CAAK,IAAA,CAAK,oBAAA,EAAsB,IAAA,CAAK,OAAA,CAAQ,qBAAqB,CAAA;AAClE,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,kDAAA,EAAoD,IAAA,CAAK,OAAA,CAAQ,qBAAqB,CAAA;AAAA,MACpG;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AAAA,IACzC;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,YAAA,EAAc;AAC7B,MAAA,IAAA,CAAK,IAAA,CAAK,iBAAA,EAAmB,IAAA,CAAK,OAAA,CAAQ,YAAY,CAAA;AAAA,IACxD;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAAA,IACrB;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAA,GAA8B;AACpC,IAAA,MAAM,GAAA,GAAyB;AAAA,MAC7B,GAAG,OAAA,CAAQ,GAAA;AAAA,MACX,GAAG,KAAK,OAAA,CAAQ;AAAA,KAClB;AAGA,IAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AAGvB,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,yBAAA,KAA8B,MAAA;AAEpE,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,qDAAqD,IAAA,CAAK,OAAA,CAAQ,OAAO,SAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA;AACpG,QAAA,OAAA,CAAQ,GAAA,CAAI,8DAAA,EAAgE,IAAA,CAAK,OAAA,CAAQ,KAAK,yBAAyB,CAAA;AACvH,QAAA,OAAA,CAAQ,GAAA,CAAI,kDAAkD,WAAW,CAAA;AAAA,MAC3E;AAEA,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,GAAA,CAAI,cAAA,GAAiB,KAAK,OAAA,CAAQ,MAAA;AAClC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,IAAI,wEAAwE,CAAA;AAAA,QACtF;AAAA,MACF,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,cAAA,GAAiB,KAAK,OAAA,CAAQ,MAAA;AAClC,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,IAAI,wEAAwE,CAAA;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,GAAA,CAAI,iEAAA,EAAmE,CAAC,CAAC,IAAI,cAAc,CAAA;AACnG,MAAA,OAAA,CAAQ,GAAA,CAAI,iEAAA,EAAmE,CAAC,CAAC,IAAI,cAAc,CAAA;AACnG,MAAA,OAAA,CAAQ,GAAA,CAAI,wEAAA,EAA0E,GAAA,CAAI,yBAAyB,CAAA;AAAA,IACrH;AAEA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,OAAA,EAAiC;AACpD,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACrB,MAAA,MAAM,IAAI,eAAe,4BAA4B,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AACnC,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,IAAI,gDAAA,EAAkD,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,IACtF;AAEA,IAAA,MAAM,UAAU,IAAA,CAAK,WAAA,CAAY,MAAM,IAAA,GAAO,IAAA,EAAM,CAAC,KAAA,KAAU;AAC7D,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,OAAA,CAAQ,KAAA,CAAM,qCAAqC,KAAK,CAAA;AAAA,MAC1D,CAAA,MAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO;AAC7B,QAAA,OAAA,CAAQ,IAAI,+DAA+D,CAAA;AAAA,MAC7E;AAAA,IACF,CAAC,CAAA;AAED,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,IAAI,qCAAA,EAAuC,OAAA,EAAS,kBAAA,EAAoB,IAAA,CAAK,YAAY,QAAQ,CAAA;AAAA,IAC3G;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,CAAC,KAAK,iBAAA,EAAmB;AAC3B,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,iBAAA,CAAkB,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,KAAS;AAC1C,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAC3B,QAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,UAAA,OAAA,CAAQ,IAAI,6CAAA,EAA+C,OAAA,CAAQ,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,QACtF;AACA,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;AC3jBO,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,IAAOE,aAAA,CAAA,UAAA,CAAW,OAAO,CAAA,EAAG;AAC1B,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,MAAM,YAAiBC,gBAAA,CAAA,IAAA,CAAK,GAAA,EAAK,gBAAgB,SAAA,EAAW,YAAA,EAAc,UAAU,WAAW,CAAA;AAC/F,EAAA,IAAOD,aAAA,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,GAAkBC,gBAAA,CAAA,IAAA;AAAA,MACtB,UAAA;AAAA,MACA,cAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAOD,aAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7B,MAAA,OAAO,UAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAA,GAAiBC,yBAAQ,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.cjs","sourcesContent":["/**\n * Type definitions for Gemini CLI SDK\n *\n * Based on Gemini CLI v0.21.0+ interface specification\n */\n\n/**\n * Gemini CLI configuration options\n */\nexport interface GeminiOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request (legacy) */\n TOOL_USE = 'tool_use',\n\n /** Tool call request (new format) */\n TOOL_CALL_REQUEST = 'tool_call_request',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event (legacy format)\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 call request event (new format)\n */\nexport interface ToolCallRequestEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_CALL_REQUEST;\n value: {\n callId: string;\n name: string;\n args: Record<string, unknown>;\n isClientInitiated: boolean;\n prompt_id: string;\n };\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n subject: string;\n description?: string;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolCallRequestEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n /** Optional temporary system instruction to append for this request only */\n temporary_system_instruction?: string;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n };\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Hook configuration types (from Gemini CLI)\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\nexport interface HookDefinition {\n matcher?: string;\n sequential?: boolean;\n hooks: HookConfig[];\n}\n\nexport interface HooksConfiguration {\n BeforeTool?: HookDefinition[];\n AfterTool?: HookDefinition[];\n BeforeAgent?: HookDefinition[];\n AfterAgent?: HookDefinition[];\n BeforeModel?: HookDefinition[];\n AfterModel?: HookDefinition[];\n BeforeToolSelection?: HookDefinition[];\n Notification?: HookDefinition[];\n SessionStart?: HookDefinition[];\n SessionEnd?: HookDefinition[];\n PreCompress?: HookDefinition[];\n disabled?: string[];\n}\n\n/**\n * Options for GeminiStreamClient\n */\nexport interface GeminiStreamOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: 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 * List of tools that are allowed to execute\n * If not specified, all tools are allowed\n * @example ['read_file', 'write_file', 'run_shell_command']\n */\n allowedTools?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n\n /**\n * Hooks configuration\n * Passed to Gemini CLI via temporary settings.json\n */\n hooks?: HooksConfiguration;\n\n /**\n * Resume from a previous session file path\n * If provided, Gemini CLI will load the session history using --resume flag\n * @example '/path/to/session-2025-01-01T12-00-abc123.json'\n */\n resumeSessionFilePath?: string;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = options.pathToNode || 'node';\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn(nodeExecutable, [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n private tempSettingsPath: string | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Create temporary settings.json if hooks are configured\n if (this.options.hooks) {\n await this.createTempSettings();\n }\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = this.options.pathToNode || 'node';\n\n // Spawn process\n this.process = spawn(nodeExecutable, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n * @param content - User message content\n * @param temporarySystemInstruction - Optional temporary system instruction to append for this request only\n */\n async sendMessage(content: string, temporarySystemInstruction?: 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 temporary_system_instruction: temporarySystemInstruction,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Send an interrupt control command\n */\n async interrupt(): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'interrupt',\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n\n // Clean up temporary settings file\n if (this.tempSettingsPath) {\n try {\n fs.unlinkSync(this.tempSettingsPath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Cleaned up temp settings:', this.tempSettingsPath);\n }\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to clean up temp settings:', error);\n }\n this.tempSettingsPath = null;\n }\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Create settings.json in GEMINI_CONFIG_DIR for hooks configuration\n *\n * Note: Gemini CLI does not support --settings-file parameter.\n * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json\n * where GEMINI_CONFIG_DIR is set via environment variable.\n */\n private async createTempSettings(): Promise<void> {\n // Get GEMINI_CONFIG_DIR from options.env\n const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;\n\n if (!geminiConfigDir) {\n throw new GeminiSDKError(\n 'GEMINI_CONFIG_DIR is required in options.env when using hooks. ' +\n 'Please set options.env.GEMINI_CONFIG_DIR to a directory path.'\n );\n }\n\n // Ensure the directory exists\n if (!fs.existsSync(geminiConfigDir)) {\n fs.mkdirSync(geminiConfigDir, { recursive: true });\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Created config directory:', geminiConfigDir);\n }\n }\n\n // Write settings.json to GEMINI_CONFIG_DIR\n this.tempSettingsPath = path.join(geminiConfigDir, 'settings.json');\n\n const settings = {\n tools: {\n enableHooks: true,\n },\n hooks: this.options.hooks,\n };\n\n try {\n fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Wrote settings to:', this.tempSettingsPath);\n console.log('[GeminiStreamClient] Settings content:', JSON.stringify(settings, null, 2));\n }\n } catch (error) {\n throw new GeminiSDKError(`Failed to write settings file: ${error}`);\n }\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Note: Do NOT use --settings-file as it's not supported by Gemini CLI\n // Settings are loaded from GEMINI_CONFIG_DIR/settings.json instead\n\n // Resume from previous session file\n if (this.options.resumeSessionFilePath) {\n args.push('--resume-from-file', this.options.resumeSessionFilePath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Resuming from session file:', this.options.resumeSessionFilePath);\n }\n }\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n // Skip debug output lines (e.g., [MESSAGE_BUS], [PolicyEngine], etc.)\n if (trimmed.startsWith('[')) {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Skipping debug output:', trimmed.substring(0, 100));\n }\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","spawn","readline","EventEmitter","readline2","fs","path","fs2","path2"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Type definitions for Gemini CLI SDK\n *\n * Based on Gemini CLI v0.21.0+ interface specification\n */\n\n/**\n * Gemini CLI configuration options\n */\nexport interface GeminiOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request (legacy) */\n TOOL_USE = 'tool_use',\n\n /** Tool call request (new format) */\n TOOL_CALL_REQUEST = 'tool_call_request',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event (legacy format)\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 call request event (new format)\n */\nexport interface ToolCallRequestEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_CALL_REQUEST;\n value: {\n callId: string;\n name: string;\n args: Record<string, unknown>;\n isClientInitiated: boolean;\n prompt_id: string;\n };\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n subject: string;\n description?: string;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolCallRequestEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n /** Optional temporary system instruction to append for this request only */\n temporary_system_instruction?: string;\n}\n\n/**\n * Control subtypes for control messages\n */\nexport type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history';\n\n/**\n * Interrupt control - stop current processing\n */\nexport interface InterruptControl {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n}\n\n/**\n * Truncate history control - remove messages from a specific index\n * Used for edit/retry functionality\n */\nexport interface TruncateHistoryControl {\n subtype: 'truncate_history';\n /** Index from which to truncate (0-based, inclusive) */\n fromIndex: number;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: InterruptControl | TruncateHistoryControl;\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Hook configuration types (from Gemini CLI)\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\nexport interface HookDefinition {\n matcher?: string;\n sequential?: boolean;\n hooks: HookConfig[];\n}\n\nexport interface HooksConfiguration {\n BeforeTool?: HookDefinition[];\n AfterTool?: HookDefinition[];\n BeforeAgent?: HookDefinition[];\n AfterAgent?: HookDefinition[];\n BeforeModel?: HookDefinition[];\n AfterModel?: HookDefinition[];\n BeforeToolSelection?: HookDefinition[];\n Notification?: HookDefinition[];\n SessionStart?: HookDefinition[];\n SessionEnd?: HookDefinition[];\n PreCompress?: HookDefinition[];\n disabled?: string[];\n}\n\n/**\n * MCP Server configuration\n * Used to configure external MCP servers in Gemini CLI\n */\nexport interface MCPServerConfig {\n /** Command to start the MCP server (for stdio transport) */\n command?: string;\n\n /** Arguments for the command */\n args?: string[];\n\n /** Working directory */\n cwd?: string;\n\n /** Environment variables */\n env?: Record<string, string>;\n\n /** URL for SSE transport */\n url?: string;\n\n /** URL for HTTP streaming transport */\n httpUrl?: string;\n\n /** Custom headers for HTTP transports */\n headers?: Record<string, string>;\n\n /** Request timeout in milliseconds (default: 600000 = 10 minutes) */\n timeout?: number;\n\n /** When true, bypass all tool call confirmations for this server */\n trust?: boolean;\n\n /** List of tool names to include (allowlist) */\n includeTools?: string[];\n\n /** List of tool names to exclude */\n excludeTools?: string[];\n}\n\n/**\n * MCP Servers configuration map\n */\nexport type MCPServersConfig = Record<string, MCPServerConfig>;\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 * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: 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 * List of tools that are allowed to execute\n * If not specified, all tools are allowed\n * @example ['read_file', 'write_file', 'run_shell_command']\n */\n allowedTools?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n\n /**\n * Hooks configuration\n * Passed to Gemini CLI via temporary settings.json\n */\n hooks?: HooksConfiguration;\n\n /**\n * MCP Servers configuration\n * Configures external MCP servers for the CLI to connect to\n * Passed to Gemini CLI via settings.json mcpServers field\n *\n * @example\n * ```typescript\n * mcpServers: {\n * 'skill-sandbox': {\n * command: 'python',\n * args: ['-m', 'skill_mcp_server'],\n * env: {\n * SKILL_PATH: '/path/to/skill',\n * CONTENT_KEY: 'base64-encoded-key'\n * },\n * trust: true\n * }\n * }\n * ```\n */\n mcpServers?: MCPServersConfig;\n\n /**\n * Resume from a previous session file path\n * If provided, Gemini CLI will load the session history using --resume flag\n * @example '/path/to/session-2025-01-01T12-00-abc123.json'\n */\n resumeSessionFilePath?: string;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = options.pathToNode || 'node';\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn(nodeExecutable, [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n private tempSettingsPath: string | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Create temporary settings.json if hooks or mcpServers are configured\n if (this.options.hooks || this.options.mcpServers) {\n await this.createTempSettings();\n }\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = this.options.pathToNode || 'node';\n\n // Spawn process\n this.process = spawn(nodeExecutable, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n * @param content - User message content\n * @param temporarySystemInstruction - Optional temporary system instruction to append for this request only\n */\n async sendMessage(content: string, temporarySystemInstruction?: 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 temporary_system_instruction: temporarySystemInstruction,\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 * Truncate chat history from a specific index\n *\n * This sends a control message to the CLI to:\n * 1. Truncate in-memory history (via GeminiChat.setHistory())\n * 2. Sync to session.json file (via ChatRecordingService)\n *\n * Used for edit/retry functionality where subsequent messages need to be discarded.\n *\n * @param fromIndex - Index from which to truncate (0-based, inclusive)\n */\n async truncateHistory(fromIndex: number): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n if (fromIndex < 0) {\n throw new GeminiSDKError('fromIndex must be non-negative');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'truncate_history',\n fromIndex,\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n\n // Clean up temporary settings file\n if (this.tempSettingsPath) {\n try {\n fs.unlinkSync(this.tempSettingsPath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Cleaned up temp settings:', this.tempSettingsPath);\n }\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to clean up temp settings:', error);\n }\n this.tempSettingsPath = null;\n }\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Create settings.json in GEMINI_CONFIG_DIR for hooks and MCP servers configuration\n *\n * Note: Gemini CLI does not support --settings-file parameter.\n * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json\n * where GEMINI_CONFIG_DIR is set via environment variable.\n */\n private async createTempSettings(): Promise<void> {\n // Get GEMINI_CONFIG_DIR from options.env\n const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;\n\n if (!geminiConfigDir) {\n throw new GeminiSDKError(\n 'GEMINI_CONFIG_DIR is required in options.env when using hooks or mcpServers. ' +\n 'Please set options.env.GEMINI_CONFIG_DIR to a directory path.'\n );\n }\n\n // Ensure the directory exists\n if (!fs.existsSync(geminiConfigDir)) {\n fs.mkdirSync(geminiConfigDir, { recursive: true });\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Created config directory:', geminiConfigDir);\n }\n }\n\n // Write settings.json to GEMINI_CONFIG_DIR\n this.tempSettingsPath = path.join(geminiConfigDir, 'settings.json');\n\n // Build settings object\n const settings: Record<string, unknown> = {};\n\n // Add hooks configuration if provided\n if (this.options.hooks) {\n settings.tools = {\n enableHooks: true,\n };\n settings.hooks = this.options.hooks;\n }\n\n // Add MCP servers configuration if provided\n if (this.options.mcpServers) {\n settings.mcpServers = this.options.mcpServers;\n }\n\n try {\n fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Wrote settings to:', this.tempSettingsPath);\n console.log('[GeminiStreamClient] Settings content:', JSON.stringify(settings, null, 2));\n }\n } catch (error) {\n throw new GeminiSDKError(`Failed to write settings file: ${error}`);\n }\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Note: Do NOT use --settings-file as it's not supported by Gemini CLI\n // Settings are loaded from GEMINI_CONFIG_DIR/settings.json instead\n\n // Resume from previous session file\n if (this.options.resumeSessionFilePath) {\n args.push('--resume-from-file', this.options.resumeSessionFilePath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Resuming from session file:', this.options.resumeSessionFilePath);\n }\n }\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n // Skip debug output lines (e.g., [MESSAGE_BUS], [PolicyEngine], etc.)\n if (trimmed.startsWith('[')) {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Skipping debug output:', trimmed.substring(0, 100));\n }\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -381,14 +381,31 @@ interface UserInputMessage {
|
|
|
381
381
|
/** Optional temporary system instruction to append for this request only */
|
|
382
382
|
temporary_system_instruction?: string;
|
|
383
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Control subtypes for control messages
|
|
386
|
+
*/
|
|
387
|
+
type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history';
|
|
388
|
+
/**
|
|
389
|
+
* Interrupt control - stop current processing
|
|
390
|
+
*/
|
|
391
|
+
interface InterruptControl {
|
|
392
|
+
subtype: 'interrupt' | 'cancel' | 'shutdown';
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Truncate history control - remove messages from a specific index
|
|
396
|
+
* Used for edit/retry functionality
|
|
397
|
+
*/
|
|
398
|
+
interface TruncateHistoryControl {
|
|
399
|
+
subtype: 'truncate_history';
|
|
400
|
+
/** Index from which to truncate (0-based, inclusive) */
|
|
401
|
+
fromIndex: number;
|
|
402
|
+
}
|
|
384
403
|
/**
|
|
385
404
|
* Control message sent to CLI
|
|
386
405
|
*/
|
|
387
406
|
interface ControlInputMessage {
|
|
388
407
|
type: JsonInputMessageType.CONTROL;
|
|
389
|
-
control:
|
|
390
|
-
subtype: 'interrupt' | 'cancel' | 'shutdown';
|
|
391
|
-
};
|
|
408
|
+
control: InterruptControl | TruncateHistoryControl;
|
|
392
409
|
session_id?: string;
|
|
393
410
|
}
|
|
394
411
|
/**
|
|
@@ -422,6 +439,38 @@ interface HooksConfiguration {
|
|
|
422
439
|
PreCompress?: HookDefinition[];
|
|
423
440
|
disabled?: string[];
|
|
424
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* MCP Server configuration
|
|
444
|
+
* Used to configure external MCP servers in Gemini CLI
|
|
445
|
+
*/
|
|
446
|
+
interface MCPServerConfig {
|
|
447
|
+
/** Command to start the MCP server (for stdio transport) */
|
|
448
|
+
command?: string;
|
|
449
|
+
/** Arguments for the command */
|
|
450
|
+
args?: string[];
|
|
451
|
+
/** Working directory */
|
|
452
|
+
cwd?: string;
|
|
453
|
+
/** Environment variables */
|
|
454
|
+
env?: Record<string, string>;
|
|
455
|
+
/** URL for SSE transport */
|
|
456
|
+
url?: string;
|
|
457
|
+
/** URL for HTTP streaming transport */
|
|
458
|
+
httpUrl?: string;
|
|
459
|
+
/** Custom headers for HTTP transports */
|
|
460
|
+
headers?: Record<string, string>;
|
|
461
|
+
/** Request timeout in milliseconds (default: 600000 = 10 minutes) */
|
|
462
|
+
timeout?: number;
|
|
463
|
+
/** When true, bypass all tool call confirmations for this server */
|
|
464
|
+
trust?: boolean;
|
|
465
|
+
/** List of tool names to include (allowlist) */
|
|
466
|
+
includeTools?: string[];
|
|
467
|
+
/** List of tool names to exclude */
|
|
468
|
+
excludeTools?: string[];
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* MCP Servers configuration map
|
|
472
|
+
*/
|
|
473
|
+
type MCPServersConfig = Record<string, MCPServerConfig>;
|
|
425
474
|
/**
|
|
426
475
|
* Options for GeminiStreamClient
|
|
427
476
|
*/
|
|
@@ -493,6 +542,27 @@ interface GeminiStreamOptions {
|
|
|
493
542
|
* Passed to Gemini CLI via temporary settings.json
|
|
494
543
|
*/
|
|
495
544
|
hooks?: HooksConfiguration;
|
|
545
|
+
/**
|
|
546
|
+
* MCP Servers configuration
|
|
547
|
+
* Configures external MCP servers for the CLI to connect to
|
|
548
|
+
* Passed to Gemini CLI via settings.json mcpServers field
|
|
549
|
+
*
|
|
550
|
+
* @example
|
|
551
|
+
* ```typescript
|
|
552
|
+
* mcpServers: {
|
|
553
|
+
* 'skill-sandbox': {
|
|
554
|
+
* command: 'python',
|
|
555
|
+
* args: ['-m', 'skill_mcp_server'],
|
|
556
|
+
* env: {
|
|
557
|
+
* SKILL_PATH: '/path/to/skill',
|
|
558
|
+
* CONTENT_KEY: 'base64-encoded-key'
|
|
559
|
+
* },
|
|
560
|
+
* trust: true
|
|
561
|
+
* }
|
|
562
|
+
* }
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
mcpServers?: MCPServersConfig;
|
|
496
566
|
/**
|
|
497
567
|
* Resume from a previous session file path
|
|
498
568
|
* If provided, Gemini CLI will load the session history using --resume flag
|
|
@@ -678,6 +748,18 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
678
748
|
* Send an interrupt control command
|
|
679
749
|
*/
|
|
680
750
|
interrupt(): Promise<void>;
|
|
751
|
+
/**
|
|
752
|
+
* Truncate chat history from a specific index
|
|
753
|
+
*
|
|
754
|
+
* This sends a control message to the CLI to:
|
|
755
|
+
* 1. Truncate in-memory history (via GeminiChat.setHistory())
|
|
756
|
+
* 2. Sync to session.json file (via ChatRecordingService)
|
|
757
|
+
*
|
|
758
|
+
* Used for edit/retry functionality where subsequent messages need to be discarded.
|
|
759
|
+
*
|
|
760
|
+
* @param fromIndex - Index from which to truncate (0-based, inclusive)
|
|
761
|
+
*/
|
|
762
|
+
truncateHistory(fromIndex: number): Promise<void>;
|
|
681
763
|
/**
|
|
682
764
|
* Stop the CLI process
|
|
683
765
|
*/
|
|
@@ -699,7 +781,7 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
699
781
|
*/
|
|
700
782
|
getPid(): number | undefined;
|
|
701
783
|
/**
|
|
702
|
-
* Create settings.json in GEMINI_CONFIG_DIR for hooks configuration
|
|
784
|
+
* Create settings.json in GEMINI_CONFIG_DIR for hooks and MCP servers configuration
|
|
703
785
|
*
|
|
704
786
|
* Note: Gemini CLI does not support --settings-file parameter.
|
|
705
787
|
* Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
|
|
@@ -793,4 +875,4 @@ declare function formatDuration(ms: number): string;
|
|
|
793
875
|
*/
|
|
794
876
|
declare function formatTokens(tokens: number): string;
|
|
795
877
|
|
|
796
|
-
export { type ControlInputMessage, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type InitEvent, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type UserInputMessage, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
|
|
878
|
+
export { type ControlInputMessage, type ControlSubtype, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type HooksConfiguration, type InitEvent, type InterruptControl, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, type MCPServerConfig, type MCPServersConfig, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type TruncateHistoryControl, type UserInputMessage, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
|
package/dist/index.d.ts
CHANGED
|
@@ -381,14 +381,31 @@ interface UserInputMessage {
|
|
|
381
381
|
/** Optional temporary system instruction to append for this request only */
|
|
382
382
|
temporary_system_instruction?: string;
|
|
383
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Control subtypes for control messages
|
|
386
|
+
*/
|
|
387
|
+
type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history';
|
|
388
|
+
/**
|
|
389
|
+
* Interrupt control - stop current processing
|
|
390
|
+
*/
|
|
391
|
+
interface InterruptControl {
|
|
392
|
+
subtype: 'interrupt' | 'cancel' | 'shutdown';
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Truncate history control - remove messages from a specific index
|
|
396
|
+
* Used for edit/retry functionality
|
|
397
|
+
*/
|
|
398
|
+
interface TruncateHistoryControl {
|
|
399
|
+
subtype: 'truncate_history';
|
|
400
|
+
/** Index from which to truncate (0-based, inclusive) */
|
|
401
|
+
fromIndex: number;
|
|
402
|
+
}
|
|
384
403
|
/**
|
|
385
404
|
* Control message sent to CLI
|
|
386
405
|
*/
|
|
387
406
|
interface ControlInputMessage {
|
|
388
407
|
type: JsonInputMessageType.CONTROL;
|
|
389
|
-
control:
|
|
390
|
-
subtype: 'interrupt' | 'cancel' | 'shutdown';
|
|
391
|
-
};
|
|
408
|
+
control: InterruptControl | TruncateHistoryControl;
|
|
392
409
|
session_id?: string;
|
|
393
410
|
}
|
|
394
411
|
/**
|
|
@@ -422,6 +439,38 @@ interface HooksConfiguration {
|
|
|
422
439
|
PreCompress?: HookDefinition[];
|
|
423
440
|
disabled?: string[];
|
|
424
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* MCP Server configuration
|
|
444
|
+
* Used to configure external MCP servers in Gemini CLI
|
|
445
|
+
*/
|
|
446
|
+
interface MCPServerConfig {
|
|
447
|
+
/** Command to start the MCP server (for stdio transport) */
|
|
448
|
+
command?: string;
|
|
449
|
+
/** Arguments for the command */
|
|
450
|
+
args?: string[];
|
|
451
|
+
/** Working directory */
|
|
452
|
+
cwd?: string;
|
|
453
|
+
/** Environment variables */
|
|
454
|
+
env?: Record<string, string>;
|
|
455
|
+
/** URL for SSE transport */
|
|
456
|
+
url?: string;
|
|
457
|
+
/** URL for HTTP streaming transport */
|
|
458
|
+
httpUrl?: string;
|
|
459
|
+
/** Custom headers for HTTP transports */
|
|
460
|
+
headers?: Record<string, string>;
|
|
461
|
+
/** Request timeout in milliseconds (default: 600000 = 10 minutes) */
|
|
462
|
+
timeout?: number;
|
|
463
|
+
/** When true, bypass all tool call confirmations for this server */
|
|
464
|
+
trust?: boolean;
|
|
465
|
+
/** List of tool names to include (allowlist) */
|
|
466
|
+
includeTools?: string[];
|
|
467
|
+
/** List of tool names to exclude */
|
|
468
|
+
excludeTools?: string[];
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* MCP Servers configuration map
|
|
472
|
+
*/
|
|
473
|
+
type MCPServersConfig = Record<string, MCPServerConfig>;
|
|
425
474
|
/**
|
|
426
475
|
* Options for GeminiStreamClient
|
|
427
476
|
*/
|
|
@@ -493,6 +542,27 @@ interface GeminiStreamOptions {
|
|
|
493
542
|
* Passed to Gemini CLI via temporary settings.json
|
|
494
543
|
*/
|
|
495
544
|
hooks?: HooksConfiguration;
|
|
545
|
+
/**
|
|
546
|
+
* MCP Servers configuration
|
|
547
|
+
* Configures external MCP servers for the CLI to connect to
|
|
548
|
+
* Passed to Gemini CLI via settings.json mcpServers field
|
|
549
|
+
*
|
|
550
|
+
* @example
|
|
551
|
+
* ```typescript
|
|
552
|
+
* mcpServers: {
|
|
553
|
+
* 'skill-sandbox': {
|
|
554
|
+
* command: 'python',
|
|
555
|
+
* args: ['-m', 'skill_mcp_server'],
|
|
556
|
+
* env: {
|
|
557
|
+
* SKILL_PATH: '/path/to/skill',
|
|
558
|
+
* CONTENT_KEY: 'base64-encoded-key'
|
|
559
|
+
* },
|
|
560
|
+
* trust: true
|
|
561
|
+
* }
|
|
562
|
+
* }
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
mcpServers?: MCPServersConfig;
|
|
496
566
|
/**
|
|
497
567
|
* Resume from a previous session file path
|
|
498
568
|
* If provided, Gemini CLI will load the session history using --resume flag
|
|
@@ -678,6 +748,18 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
678
748
|
* Send an interrupt control command
|
|
679
749
|
*/
|
|
680
750
|
interrupt(): Promise<void>;
|
|
751
|
+
/**
|
|
752
|
+
* Truncate chat history from a specific index
|
|
753
|
+
*
|
|
754
|
+
* This sends a control message to the CLI to:
|
|
755
|
+
* 1. Truncate in-memory history (via GeminiChat.setHistory())
|
|
756
|
+
* 2. Sync to session.json file (via ChatRecordingService)
|
|
757
|
+
*
|
|
758
|
+
* Used for edit/retry functionality where subsequent messages need to be discarded.
|
|
759
|
+
*
|
|
760
|
+
* @param fromIndex - Index from which to truncate (0-based, inclusive)
|
|
761
|
+
*/
|
|
762
|
+
truncateHistory(fromIndex: number): Promise<void>;
|
|
681
763
|
/**
|
|
682
764
|
* Stop the CLI process
|
|
683
765
|
*/
|
|
@@ -699,7 +781,7 @@ declare class GeminiStreamClient extends EventEmitter$1 {
|
|
|
699
781
|
*/
|
|
700
782
|
getPid(): number | undefined;
|
|
701
783
|
/**
|
|
702
|
-
* Create settings.json in GEMINI_CONFIG_DIR for hooks configuration
|
|
784
|
+
* Create settings.json in GEMINI_CONFIG_DIR for hooks and MCP servers configuration
|
|
703
785
|
*
|
|
704
786
|
* Note: Gemini CLI does not support --settings-file parameter.
|
|
705
787
|
* Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
|
|
@@ -793,4 +875,4 @@ declare function formatDuration(ms: number): string;
|
|
|
793
875
|
*/
|
|
794
876
|
declare function formatTokens(tokens: number): string;
|
|
795
877
|
|
|
796
|
-
export { type ControlInputMessage, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type InitEvent, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type UserInputMessage, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
|
|
878
|
+
export { type ControlInputMessage, type ControlSubtype, type ErrorEvent, ExitCode, GeminiClient, type GeminiOptions, GeminiSDKError, GeminiStreamClient, type GeminiStreamOptions, type HooksConfiguration, type InitEvent, type InterruptControl, type JsonInputMessage, JsonInputMessageType, type JsonStreamEvent, JsonStreamEventType, type MCPServerConfig, type MCPServersConfig, type MessageEvent, ProcessStatus, type QueryResult, type ResultEvent, type StreamStats, type ThoughtEvent, type ToolPermissionDecision, type ToolPermissionRequest, type ToolResultEvent, type ToolUseEvent, type TruncateHistoryControl, type UserInputMessage, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
|
package/dist/index.js
CHANGED
|
@@ -398,7 +398,7 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
398
398
|
throw new GeminiSDKError("Process already started");
|
|
399
399
|
}
|
|
400
400
|
this.status = "running" /* RUNNING */;
|
|
401
|
-
if (this.options.hooks) {
|
|
401
|
+
if (this.options.hooks || this.options.mcpServers) {
|
|
402
402
|
await this.createTempSettings();
|
|
403
403
|
}
|
|
404
404
|
const args = this.buildCommand();
|
|
@@ -474,6 +474,34 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
474
474
|
};
|
|
475
475
|
this.writeMessage(message);
|
|
476
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Truncate chat history from a specific index
|
|
479
|
+
*
|
|
480
|
+
* This sends a control message to the CLI to:
|
|
481
|
+
* 1. Truncate in-memory history (via GeminiChat.setHistory())
|
|
482
|
+
* 2. Sync to session.json file (via ChatRecordingService)
|
|
483
|
+
*
|
|
484
|
+
* Used for edit/retry functionality where subsequent messages need to be discarded.
|
|
485
|
+
*
|
|
486
|
+
* @param fromIndex - Index from which to truncate (0-based, inclusive)
|
|
487
|
+
*/
|
|
488
|
+
async truncateHistory(fromIndex) {
|
|
489
|
+
if (!this.isReady()) {
|
|
490
|
+
throw new GeminiSDKError("Client not ready. Call start() first.");
|
|
491
|
+
}
|
|
492
|
+
if (fromIndex < 0) {
|
|
493
|
+
throw new GeminiSDKError("fromIndex must be non-negative");
|
|
494
|
+
}
|
|
495
|
+
const message = {
|
|
496
|
+
type: "control" /* CONTROL */,
|
|
497
|
+
control: {
|
|
498
|
+
subtype: "truncate_history",
|
|
499
|
+
fromIndex
|
|
500
|
+
},
|
|
501
|
+
session_id: this.options.sessionId
|
|
502
|
+
};
|
|
503
|
+
this.writeMessage(message);
|
|
504
|
+
}
|
|
477
505
|
/**
|
|
478
506
|
* Stop the CLI process
|
|
479
507
|
*/
|
|
@@ -549,7 +577,7 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
549
577
|
return this.process?.pid;
|
|
550
578
|
}
|
|
551
579
|
/**
|
|
552
|
-
* Create settings.json in GEMINI_CONFIG_DIR for hooks configuration
|
|
580
|
+
* Create settings.json in GEMINI_CONFIG_DIR for hooks and MCP servers configuration
|
|
553
581
|
*
|
|
554
582
|
* Note: Gemini CLI does not support --settings-file parameter.
|
|
555
583
|
* Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json
|
|
@@ -559,7 +587,7 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
559
587
|
const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;
|
|
560
588
|
if (!geminiConfigDir) {
|
|
561
589
|
throw new GeminiSDKError(
|
|
562
|
-
"GEMINI_CONFIG_DIR is required in options.env when using hooks. Please set options.env.GEMINI_CONFIG_DIR to a directory path."
|
|
590
|
+
"GEMINI_CONFIG_DIR is required in options.env when using hooks or mcpServers. Please set options.env.GEMINI_CONFIG_DIR to a directory path."
|
|
563
591
|
);
|
|
564
592
|
}
|
|
565
593
|
if (!fs.existsSync(geminiConfigDir)) {
|
|
@@ -569,12 +597,16 @@ var GeminiStreamClient = class extends EventEmitter {
|
|
|
569
597
|
}
|
|
570
598
|
}
|
|
571
599
|
this.tempSettingsPath = path2.join(geminiConfigDir, "settings.json");
|
|
572
|
-
const settings = {
|
|
573
|
-
|
|
600
|
+
const settings = {};
|
|
601
|
+
if (this.options.hooks) {
|
|
602
|
+
settings.tools = {
|
|
574
603
|
enableHooks: true
|
|
575
|
-
}
|
|
576
|
-
hooks
|
|
577
|
-
}
|
|
604
|
+
};
|
|
605
|
+
settings.hooks = this.options.hooks;
|
|
606
|
+
}
|
|
607
|
+
if (this.options.mcpServers) {
|
|
608
|
+
settings.mcpServers = this.options.mcpServers;
|
|
609
|
+
}
|
|
578
610
|
try {
|
|
579
611
|
fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
580
612
|
if (this.options.debug) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","EventEmitter","spawn","readline2","path","fs2"],"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 * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request (legacy) */\n TOOL_USE = 'tool_use',\n\n /** Tool call request (new format) */\n TOOL_CALL_REQUEST = 'tool_call_request',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event (legacy format)\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 call request event (new format)\n */\nexport interface ToolCallRequestEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_CALL_REQUEST;\n value: {\n callId: string;\n name: string;\n args: Record<string, unknown>;\n isClientInitiated: boolean;\n prompt_id: string;\n };\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n subject: string;\n description?: string;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolCallRequestEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n /** Optional temporary system instruction to append for this request only */\n temporary_system_instruction?: string;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n };\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Hook configuration types (from Gemini CLI)\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\nexport interface HookDefinition {\n matcher?: string;\n sequential?: boolean;\n hooks: HookConfig[];\n}\n\nexport interface HooksConfiguration {\n BeforeTool?: HookDefinition[];\n AfterTool?: HookDefinition[];\n BeforeAgent?: HookDefinition[];\n AfterAgent?: HookDefinition[];\n BeforeModel?: HookDefinition[];\n AfterModel?: HookDefinition[];\n BeforeToolSelection?: HookDefinition[];\n Notification?: HookDefinition[];\n SessionStart?: HookDefinition[];\n SessionEnd?: HookDefinition[];\n PreCompress?: HookDefinition[];\n disabled?: string[];\n}\n\n/**\n * Options for GeminiStreamClient\n */\nexport interface GeminiStreamOptions {\n /**\n * Path to Gemini CLI executable\n * @example 'node_modules/@google/gemini-cli/bundle/gemini.js'\n */\n pathToGeminiCLI: string;\n\n /**\n * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: 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 * List of tools that are allowed to execute\n * If not specified, all tools are allowed\n * @example ['read_file', 'write_file', 'run_shell_command']\n */\n allowedTools?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n\n /**\n * Hooks configuration\n * Passed to Gemini CLI via temporary settings.json\n */\n hooks?: HooksConfiguration;\n\n /**\n * Resume from a previous session file path\n * If provided, Gemini CLI will load the session history using --resume flag\n * @example '/path/to/session-2025-01-01T12-00-abc123.json'\n */\n resumeSessionFilePath?: string;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = options.pathToNode || 'node';\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn(nodeExecutable, [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n private tempSettingsPath: string | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Create temporary settings.json if hooks are configured\n if (this.options.hooks) {\n await this.createTempSettings();\n }\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = this.options.pathToNode || 'node';\n\n // Spawn process\n this.process = spawn(nodeExecutable, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n * @param content - User message content\n * @param temporarySystemInstruction - Optional temporary system instruction to append for this request only\n */\n async sendMessage(content: string, temporarySystemInstruction?: 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 temporary_system_instruction: temporarySystemInstruction,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Send an interrupt control command\n */\n async interrupt(): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'interrupt',\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n\n // Clean up temporary settings file\n if (this.tempSettingsPath) {\n try {\n fs.unlinkSync(this.tempSettingsPath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Cleaned up temp settings:', this.tempSettingsPath);\n }\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to clean up temp settings:', error);\n }\n this.tempSettingsPath = null;\n }\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Create settings.json in GEMINI_CONFIG_DIR for hooks configuration\n *\n * Note: Gemini CLI does not support --settings-file parameter.\n * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json\n * where GEMINI_CONFIG_DIR is set via environment variable.\n */\n private async createTempSettings(): Promise<void> {\n // Get GEMINI_CONFIG_DIR from options.env\n const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;\n\n if (!geminiConfigDir) {\n throw new GeminiSDKError(\n 'GEMINI_CONFIG_DIR is required in options.env when using hooks. ' +\n 'Please set options.env.GEMINI_CONFIG_DIR to a directory path.'\n );\n }\n\n // Ensure the directory exists\n if (!fs.existsSync(geminiConfigDir)) {\n fs.mkdirSync(geminiConfigDir, { recursive: true });\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Created config directory:', geminiConfigDir);\n }\n }\n\n // Write settings.json to GEMINI_CONFIG_DIR\n this.tempSettingsPath = path.join(geminiConfigDir, 'settings.json');\n\n const settings = {\n tools: {\n enableHooks: true,\n },\n hooks: this.options.hooks,\n };\n\n try {\n fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Wrote settings to:', this.tempSettingsPath);\n console.log('[GeminiStreamClient] Settings content:', JSON.stringify(settings, null, 2));\n }\n } catch (error) {\n throw new GeminiSDKError(`Failed to write settings file: ${error}`);\n }\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Note: Do NOT use --settings-file as it's not supported by Gemini CLI\n // Settings are loaded from GEMINI_CONFIG_DIR/settings.json instead\n\n // Resume from previous session file\n if (this.options.resumeSessionFilePath) {\n args.push('--resume-from-file', this.options.resumeSessionFilePath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Resuming from session file:', this.options.resumeSessionFilePath);\n }\n }\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n // Skip debug output lines (e.g., [MESSAGE_BUS], [PolicyEngine], etc.)\n if (trimmed.startsWith('[')) {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Skipping debug output:', trimmed.substring(0, 100));\n }\n return;\n }\n\n try {\n const event = JSON.parse(trimmed) as JsonStreamEvent;\n this.handleEvent(event);\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to parse JSON:', trimmed);\n console.error('[GeminiStreamClient] Error:', error);\n }\n });\n\n this.readlineInterface.on('close', () => {\n // stdout closed\n if (this.options.debug) {\n console.log('[GeminiStreamClient] readline interface closed');\n }\n });\n }\n\n /**\n * Handle a JSON stream event\n */\n private handleEvent(event: JsonStreamEvent): void {\n // Capture INIT event\n if (event.type === JsonStreamEventType.INIT) {\n this.initEvent = event as InitEvent;\n\n // Clear init timeout\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n this.emit('ready', this.initEvent);\n }\n\n // Emit event to listeners\n this.emit('event', event);\n }\n\n /**\n * Wait for INIT event\n */\n private async waitForInit(): Promise<void> {\n const timeout = this.options.initTimeout || 30000;\n\n return new Promise((resolve, reject) => {\n // Already initialized?\n if (this.initEvent) {\n resolve();\n return;\n }\n\n // Set timeout\n this.initTimeout = setTimeout(() => {\n reject(new GeminiSDKError('Initialization timeout', undefined, { timeout }));\n }, timeout);\n\n // Wait for ready event\n this.once('ready', () => {\n resolve();\n });\n\n // Or error\n this.once('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Handle process exit\n */\n private handleProcessExit(code: number | null, signal: NodeJS.Signals | null): void {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Process exited:', { code, signal });\n }\n\n if (code !== 0 && code !== null) {\n this.status = ProcessStatus.ERROR;\n this.emit('error', new GeminiSDKError(`Process exited with code ${code}`, code));\n } else {\n this.status = ProcessStatus.COMPLETED;\n }\n\n this.emit('stopped', code);\n\n // Cleanup\n this.process = null;\n this.stdinStream = null;\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n }\n\n /**\n * Handle process error\n */\n private handleProcessError(error: Error): void {\n console.error('[GeminiStreamClient] Process error:', error);\n this.status = ProcessStatus.ERROR;\n this.emit('error', error);\n }\n}\n","/**\n * Utility functions for Gemini CLI SDK\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * Find Gemini CLI executable path\n *\n * Searches in common locations:\n * 1. node_modules/@google/gemini-cli/bundle/gemini.js\n * 2. Custom path from environment variable\n * 3. Global installation\n *\n * @param cwd - Current working directory\n * @returns string - Path to Gemini CLI executable\n * @throws Error if Gemini CLI is not found\n */\nexport function findGeminiCLI(cwd: string = process.cwd()): string {\n // 1. Check environment variable\n if (process.env.GEMINI_CLI_PATH) {\n const envPath = process.env.GEMINI_CLI_PATH;\n if (fs.existsSync(envPath)) {\n return envPath;\n }\n }\n\n // 2. Check local node_modules\n const localPath = path.join(cwd, 'node_modules', '@google', 'gemini-cli', 'bundle', 'gemini.js');\n if (fs.existsSync(localPath)) {\n return localPath;\n }\n\n // 3. Check parent directories (monorepo support)\n let currentDir = cwd;\n for (let i = 0; i < 5; i++) {\n const parentPath = path.join(\n currentDir,\n 'node_modules',\n '@google',\n 'gemini-cli',\n 'bundle',\n 'gemini.js',\n );\n if (fs.existsSync(parentPath)) {\n return parentPath;\n }\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n\n throw new Error(\n 'Gemini CLI not found. Please install @google/gemini-cli or set GEMINI_CLI_PATH environment variable.',\n );\n}\n\n/**\n * Validate API key\n *\n * @param apiKey - API key to validate\n * @returns boolean - True if valid\n */\nexport function validateApiKey(apiKey?: string): boolean {\n if (!apiKey) {\n const envKey = process.env.GOOGLE_API_KEY;\n return !!envKey && envKey.length > 0;\n }\n return apiKey.length > 0;\n}\n\n/**\n * Get API key from environment or options\n *\n * @param apiKey - Optional API key from options\n * @returns string - API key\n * @throws Error if API key is not found\n */\nexport function getApiKey(apiKey?: string): string {\n const key = apiKey || process.env.GOOGLE_API_KEY;\n if (!key) {\n throw new Error(\n 'API key not found. Please provide apiKey option or set GOOGLE_API_KEY environment variable.',\n );\n }\n return key;\n}\n\n/**\n * Parse model name and validate\n *\n * @param model - Model name\n * @returns string - Validated model name\n */\nexport function validateModel(model?: string): string {\n const defaultModel = 'gemini-2.0-flash-exp';\n if (!model) {\n return defaultModel;\n }\n\n // Basic validation: should start with 'gemini-'\n if (!model.startsWith('gemini-')) {\n console.warn(`Warning: Model name \"${model}\" does not start with \"gemini-\"`);\n }\n\n return model;\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n *\n * @param ms - Duration in milliseconds\n * @returns string - Formatted duration\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(0);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Format token count with commas\n *\n * @param tokens - Token count\n * @returns string - Formatted token count\n */\nexport function formatTokens(tokens: number): string {\n return tokens.toLocaleString();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/query.ts","../src/client.ts","../src/streamClient.ts","../src/utils.ts"],"names":["JsonStreamEventType","ExitCode","ProcessStatus","JsonInputMessageType","EventEmitter","spawn","readline2","path","fs2"],"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 * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: string;\n\n /**\n * Google AI API Key\n * Can also be set via GEMINI_API_KEY environment variable\n */\n apiKey?: string;\n\n /**\n * Model name\n * @default 'gemini-2.0-flash-exp'\n * @example 'gemini-2.0-flash-exp', 'gemini-1.5-pro'\n */\n model?: string;\n\n /**\n * Working directory for CLI execution\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * System prompt (not directly supported by CLI, needs workaround)\n */\n systemPrompt?: string;\n\n /**\n * Approval mode for tool execution\n * - default: Prompt for approval\n * - auto_edit: Auto-approve edit tools\n * - yolo: Auto-approve all tools\n * @default 'default'\n */\n approvalMode?: 'default' | 'auto_edit' | 'yolo';\n\n /**\n * List of tools that can run without confirmation\n * @example ['read', 'write', 'bash']\n */\n allowedTools?: string[];\n\n /**\n * List of allowed MCP server names\n */\n allowedMcpServerNames?: string[];\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Session ID to resume\n * Use 'latest' to resume the most recent session\n */\n resumeSessionId?: string;\n\n /**\n * Enable sandbox mode\n * @default false\n */\n sandbox?: boolean;\n\n /**\n * Additional directories to include in workspace\n */\n includeDirectories?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Timeout in milliseconds\n * @default undefined (no timeout)\n */\n timeout?: number;\n\n /**\n * Permission callback for tool execution\n * Called when a tool requires approval (when approvalMode is 'default')\n * Return true to approve, false to deny\n * If not provided, falls back to Gemini CLI's built-in approval mechanism\n */\n onPermissionRequest?: (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;\n}\n\n/**\n * Tool permission request\n */\nexport interface ToolPermissionRequest {\n /** Unique tool call ID */\n toolId: string;\n\n /** Tool name (e.g., 'write_file', 'run_shell_command') */\n toolName: string;\n\n /** Tool parameters */\n parameters: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Tool permission decision from host application\n */\nexport interface ToolPermissionDecision {\n /** Whether to approve the tool execution */\n approved: boolean;\n\n /** Optional reason for the decision (for logging) */\n reason?: string;\n}\n\n/**\n * JSON Stream Event Types\n *\n * Based on: @google/gemini-cli/packages/core/src/output/types.ts\n * Plus additional event types actually sent by CLI\n */\nexport enum JsonStreamEventType {\n /** Session initialization */\n INIT = 'init',\n\n /** Message content (user/assistant) */\n MESSAGE = 'message',\n\n /** Tool call request (legacy) */\n TOOL_USE = 'tool_use',\n\n /** Tool call request (new format) */\n TOOL_CALL_REQUEST = 'tool_call_request',\n\n /** Tool execution result */\n TOOL_RESULT = 'tool_result',\n\n /** Thought/reasoning process */\n THOUGHT = 'thought',\n\n /** Error event */\n ERROR = 'error',\n\n /** Final result */\n RESULT = 'result',\n\n // Additional event types actually sent by Gemini CLI\n /** Message content chunk (streaming) */\n CONTENT = 'content',\n\n /** Message completion with metadata */\n FINISHED = 'finished',\n\n /** Model information */\n MODEL_INFO = 'model_info',\n}\n\n/**\n * Base event interface\n */\nexport interface BaseJsonStreamEvent {\n type: JsonStreamEventType;\n timestamp: string; // ISO 8601 format\n}\n\n/**\n * Session initialization event\n */\nexport interface InitEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.INIT;\n session_id: string;\n model: string;\n conversation_file_path?: string; // Added for AoE Desktop integration\n}\n\n/**\n * Message event\n */\nexport interface MessageEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MESSAGE;\n role: 'user' | 'assistant';\n content: string;\n delta?: boolean; // true for incremental content\n}\n\n/**\n * Tool call event (legacy format)\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 call request event (new format)\n */\nexport interface ToolCallRequestEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_CALL_REQUEST;\n value: {\n callId: string;\n name: string;\n args: Record<string, unknown>;\n isClientInitiated: boolean;\n prompt_id: string;\n };\n}\n\n/**\n * Tool execution result event\n */\nexport interface ToolResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.TOOL_RESULT;\n tool_id: string;\n status: 'success' | 'error';\n output?: string;\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Thought summary containing subject and description\n */\nexport interface ThoughtSummary {\n subject: string;\n description?: string;\n}\n\n/**\n * Thought/reasoning event\n * Emitted by Gemini CLI when the model is thinking\n */\nexport interface ThoughtEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.THOUGHT;\n subject: string;\n description?: string;\n traceId?: string;\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.ERROR;\n severity: 'warning' | 'error';\n message: string;\n}\n\n/**\n * Stream statistics\n */\nexport interface StreamStats {\n total_tokens: number;\n input_tokens: number;\n output_tokens: number;\n duration_ms: number;\n tool_calls: number;\n}\n\n/**\n * Final result event\n */\nexport interface ResultEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.RESULT;\n status: 'success' | 'error';\n error?: {\n type: string;\n message: string;\n };\n stats?: StreamStats;\n}\n\n/**\n * Content event (streaming message chunk)\n * This is the actual event type sent by Gemini CLI for message content\n */\nexport interface ContentEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.CONTENT;\n value: string;\n traceId?: string;\n}\n\n/**\n * Finished event (message completion with metadata)\n */\nexport interface FinishedEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.FINISHED;\n value: {\n reason: string;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n trafficType?: string;\n promptTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n candidatesTokensDetails?: Array<{\n modality: string;\n tokenCount: number;\n }>;\n thoughtsTokenCount?: number;\n };\n };\n}\n\n/**\n * Model information event\n */\nexport interface ModelInfoEvent extends BaseJsonStreamEvent {\n type: JsonStreamEventType.MODEL_INFO;\n value: string;\n}\n\n/**\n * Union type of all JSON stream events\n */\nexport type JsonStreamEvent =\n | InitEvent\n | MessageEvent\n | ToolUseEvent\n | ToolCallRequestEvent\n | ToolResultEvent\n | ThoughtEvent\n | ErrorEvent\n | ResultEvent\n | ContentEvent\n | FinishedEvent\n | ModelInfoEvent;\n\n/**\n * Gemini CLI exit codes\n */\nexport enum ExitCode {\n /** Success */\n SUCCESS = 0,\n\n /** General error */\n GENERAL_ERROR = 1,\n\n /** Configuration error */\n CONFIG_ERROR = 2,\n\n /** User interrupted (Ctrl+C) */\n USER_INTERRUPTED = 130,\n}\n\n/**\n * CLI process status\n */\nexport enum ProcessStatus {\n /** Not started */\n IDLE = 'idle',\n\n /** Running */\n RUNNING = 'running',\n\n /** Completed successfully */\n COMPLETED = 'completed',\n\n /** Cancelled by user */\n CANCELLED = 'cancelled',\n\n /** Error occurred */\n ERROR = 'error',\n}\n\n/**\n * Gemini SDK Error\n */\nexport class GeminiSDKError extends Error {\n constructor(\n message: string,\n public code?: ExitCode,\n public details?: unknown,\n ) {\n super(message);\n this.name = 'GeminiSDKError';\n // captureStackTrace is available in V8 (Node.js) but not in all environments\n if (typeof (Error as any).captureStackTrace === 'function') {\n (Error as any).captureStackTrace(this, GeminiSDKError);\n }\n }\n}\n\n/**\n * Query result (accumulated from stream)\n */\nexport interface QueryResult {\n /** Session ID */\n sessionId: string;\n\n /** Model used */\n model: string;\n\n /** Full assistant response text */\n response: string;\n\n /** Tool calls made during the query */\n toolCalls: Array<{\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: {\n status: 'success' | 'error';\n output?: string;\n error?: { type: string; message: string };\n };\n }>;\n\n /** Final statistics */\n stats?: StreamStats;\n\n /** Final status */\n status: 'success' | 'error';\n\n /** Error if status is 'error' */\n error?: {\n type: string;\n message: string;\n };\n}\n\n/**\n * Input message types for Stream Client (SDK → CLI via stdin)\n */\nexport enum JsonInputMessageType {\n /** User message */\n USER = 'user',\n\n /** Control command */\n CONTROL = 'control',\n}\n\n/**\n * User message sent to CLI\n */\nexport interface UserInputMessage {\n type: JsonInputMessageType.USER;\n content: string;\n session_id?: string;\n /** Optional temporary system instruction to append for this request only */\n temporary_system_instruction?: string;\n}\n\n/**\n * Control subtypes for control messages\n */\nexport type ControlSubtype = 'interrupt' | 'cancel' | 'shutdown' | 'truncate_history';\n\n/**\n * Interrupt control - stop current processing\n */\nexport interface InterruptControl {\n subtype: 'interrupt' | 'cancel' | 'shutdown';\n}\n\n/**\n * Truncate history control - remove messages from a specific index\n * Used for edit/retry functionality\n */\nexport interface TruncateHistoryControl {\n subtype: 'truncate_history';\n /** Index from which to truncate (0-based, inclusive) */\n fromIndex: number;\n}\n\n/**\n * Control message sent to CLI\n */\nexport interface ControlInputMessage {\n type: JsonInputMessageType.CONTROL;\n control: InterruptControl | TruncateHistoryControl;\n session_id?: string;\n}\n\n/**\n * Union type for input messages\n */\nexport type JsonInputMessage = UserInputMessage | ControlInputMessage;\n\n/**\n * Hook configuration types (from Gemini CLI)\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\nexport interface HookDefinition {\n matcher?: string;\n sequential?: boolean;\n hooks: HookConfig[];\n}\n\nexport interface HooksConfiguration {\n BeforeTool?: HookDefinition[];\n AfterTool?: HookDefinition[];\n BeforeAgent?: HookDefinition[];\n AfterAgent?: HookDefinition[];\n BeforeModel?: HookDefinition[];\n AfterModel?: HookDefinition[];\n BeforeToolSelection?: HookDefinition[];\n Notification?: HookDefinition[];\n SessionStart?: HookDefinition[];\n SessionEnd?: HookDefinition[];\n PreCompress?: HookDefinition[];\n disabled?: string[];\n}\n\n/**\n * MCP Server configuration\n * Used to configure external MCP servers in Gemini CLI\n */\nexport interface MCPServerConfig {\n /** Command to start the MCP server (for stdio transport) */\n command?: string;\n\n /** Arguments for the command */\n args?: string[];\n\n /** Working directory */\n cwd?: string;\n\n /** Environment variables */\n env?: Record<string, string>;\n\n /** URL for SSE transport */\n url?: string;\n\n /** URL for HTTP streaming transport */\n httpUrl?: string;\n\n /** Custom headers for HTTP transports */\n headers?: Record<string, string>;\n\n /** Request timeout in milliseconds (default: 600000 = 10 minutes) */\n timeout?: number;\n\n /** When true, bypass all tool call confirmations for this server */\n trust?: boolean;\n\n /** List of tool names to include (allowlist) */\n includeTools?: string[];\n\n /** List of tool names to exclude */\n excludeTools?: string[];\n}\n\n/**\n * MCP Servers configuration map\n */\nexport type MCPServersConfig = Record<string, MCPServerConfig>;\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 * Path to Node.js executable (optional)\n * If not specified, uses 'node' from PATH\n * Useful for packaged Electron apps with bundled Node.js\n * @example '/Applications/MyApp.app/Contents/Resources/nodejs/node'\n * @default 'node'\n */\n pathToNode?: 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 * List of tools that are allowed to execute\n * If not specified, all tools are allowed\n * @example ['read_file', 'write_file', 'run_shell_command']\n */\n allowedTools?: string[];\n\n /**\n * Custom environment variables\n */\n env?: Record<string, string>;\n\n /**\n * Enable debug mode\n * @default false\n */\n debug?: boolean;\n\n /**\n * Timeout for process initialization (ms)\n * @default 30000\n */\n initTimeout?: number;\n\n /**\n * Hooks configuration\n * Passed to Gemini CLI via temporary settings.json\n */\n hooks?: HooksConfiguration;\n\n /**\n * MCP Servers configuration\n * Configures external MCP servers for the CLI to connect to\n * Passed to Gemini CLI via settings.json mcpServers field\n *\n * @example\n * ```typescript\n * mcpServers: {\n * 'skill-sandbox': {\n * command: 'python',\n * args: ['-m', 'skill_mcp_server'],\n * env: {\n * SKILL_PATH: '/path/to/skill',\n * CONTENT_KEY: 'base64-encoded-key'\n * },\n * trust: true\n * }\n * }\n * ```\n */\n mcpServers?: MCPServersConfig;\n\n /**\n * Resume from a previous session file path\n * If provided, Gemini CLI will load the session history using --resume flag\n * @example '/path/to/session-2025-01-01T12-00-abc123.json'\n */\n resumeSessionFilePath?: string;\n}\n","/**\n * Core query function for Gemini CLI SDK\n *\n * Spawns Gemini CLI as subprocess and streams JSON events\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport * as readline from 'readline';\nimport type { GeminiOptions, JsonStreamEvent } from './types';\nimport { GeminiSDKError, ExitCode } from './types';\n\n/**\n * Build CLI arguments from options\n */\nfunction buildCliArgs(options: GeminiOptions, prompt: string): string[] {\n const args: string[] = [];\n\n // Output format: always use stream-json\n args.push('--output-format', 'stream-json');\n\n // Model\n if (options.model) {\n args.push('--model', options.model);\n }\n\n // Approval mode\n if (options.approvalMode) {\n args.push('--approval-mode', options.approvalMode);\n }\n\n // Allowed tools\n if (options.allowedTools && options.allowedTools.length > 0) {\n args.push('--allowed-tools', options.allowedTools.join(','));\n }\n\n // Allowed MCP servers\n if (options.allowedMcpServerNames && options.allowedMcpServerNames.length > 0) {\n args.push('--allowed-mcp-server-names', options.allowedMcpServerNames.join(','));\n }\n\n // Resume session\n if (options.resumeSessionId) {\n args.push('--resume', options.resumeSessionId);\n }\n\n // Sandbox mode\n if (options.sandbox) {\n args.push('--sandbox');\n }\n\n // Include directories\n if (options.includeDirectories && options.includeDirectories.length > 0) {\n args.push('--include-directories', options.includeDirectories.join(','));\n }\n\n // Debug mode\n if (options.debug) {\n args.push('--debug');\n }\n\n // Positional argument: user prompt (no -- needed)\n args.push(prompt);\n\n return args;\n}\n\n/**\n * Build environment variables\n */\nfunction buildEnv(options: GeminiOptions): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...options.env,\n };\n\n // Auto-detect Vertex AI mode by API key prefix\n // Vertex AI keys start with \"AQ.\" (e.g., AQ.Ab8RN6K...)\n // Standard Gemini API keys start with \"AI...\" (e.g., AIzaSy...)\n const isVertexAIKey = options.apiKey?.startsWith('AQ.');\n const useVertexAI = isVertexAIKey || env.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n // API Key - Gemini CLI requires GEMINI_API_KEY (or GOOGLE_API_KEY for Vertex AI)\n if (options.apiKey) {\n if (useVertexAI) {\n // Vertex AI mode: use GOOGLE_API_KEY\n env.GOOGLE_API_KEY = options.apiKey;\n env.GOOGLE_GENAI_USE_VERTEXAI = 'true';\n if (options.debug) {\n console.log('[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n } else {\n // Standard mode: use GEMINI_API_KEY\n env.GEMINI_API_KEY = options.apiKey;\n if (options.debug) {\n console.log('[SDK] Standard mode: Setting GEMINI_API_KEY:', options.apiKey.substring(0, 10) + '...');\n }\n }\n }\n\n // Unset GOOGLE_API_KEY to prevent Gemini CLI from using it (unless using Vertex AI)\n // (Gemini CLI prefers GOOGLE_API_KEY over GEMINI_API_KEY when both are set)\n if (!useVertexAI && env.GOOGLE_API_KEY) {\n delete env.GOOGLE_API_KEY;\n if (options.debug) {\n console.log('[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)');\n }\n }\n\n // Debug mode\n if (options.debug) {\n env.DEBUG = '1';\n console.log('[SDK] Environment variables set:', {\n GEMINI_API_KEY: env.GEMINI_API_KEY ? '***' : undefined,\n GOOGLE_API_KEY: env.GOOGLE_API_KEY ? '***' : undefined,\n GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,\n GEMINI_CONFIG_DIR: env.GEMINI_CONFIG_DIR,\n });\n }\n\n return env;\n}\n\n/**\n * Query Gemini CLI and stream JSON events\n *\n * @param prompt - User prompt\n * @param options - Gemini configuration options\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n *\n * @example\n * ```typescript\n * import { query } from '@google/gemini-cli-sdk';\n *\n * const stream = query('Hello, Gemini!', {\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * for await (const event of stream) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n * ```\n */\nexport async function* query(\n prompt: string,\n options: GeminiOptions,\n): AsyncGenerator<JsonStreamEvent> {\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n\n if (!options.apiKey && !process.env.GEMINI_API_KEY) {\n throw new GeminiSDKError(\n 'apiKey is required (or set GEMINI_API_KEY environment variable)',\n );\n }\n\n // Build CLI arguments and environment\n const args = buildCliArgs(options, prompt);\n const env = buildEnv(options);\n const cwd = options.cwd || process.cwd();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = options.pathToNode || 'node';\n\n // Spawn Gemini CLI subprocess\n let geminiProcess: ChildProcess;\n try {\n geminiProcess = spawn(nodeExecutable, [options.pathToGeminiCLI, ...args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n cwd,\n });\n } catch (error) {\n throw new GeminiSDKError('Failed to spawn Gemini CLI process', undefined, error);\n }\n\n // Handle stderr (CLI internal logs)\n const stderrChunks: Buffer[] = [];\n geminiProcess.stderr?.on('data', (data: Buffer) => {\n stderrChunks.push(data);\n if (options.debug) {\n console.error('[Gemini CLI stderr]:', data.toString());\n }\n });\n\n // Setup timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n geminiProcess.kill('SIGTERM');\n }, options.timeout);\n }\n\n // Create readline interface for stdout\n const rl = readline.createInterface({\n input: geminiProcess.stdout!,\n crlfDelay: Infinity,\n });\n\n // Track if we've yielded any events\n let hasYieldedEvents = false;\n\n try {\n // Stream JSON-Lines output\n for await (const line of rl) {\n try {\n const event = JSON.parse(line) as JsonStreamEvent;\n hasYieldedEvents = true;\n yield event;\n } catch (parseError) {\n // Log parse errors but continue processing\n if (options.debug) {\n console.error('[Gemini SDK] Failed to parse JSON line:', line);\n console.error('[Gemini SDK] Parse error:', parseError);\n }\n }\n }\n } catch (error) {\n throw new GeminiSDKError('Failed to read from Gemini CLI stdout', undefined, error);\n } finally {\n // Clear timeout\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n // Wait for process to exit\n const exitCode = await new Promise<number>((resolve, reject) => {\n geminiProcess.on('exit', (code, signal) => {\n if (signal) {\n reject(\n new GeminiSDKError(\n `Gemini CLI process was killed with signal ${signal}`,\n ExitCode.USER_INTERRUPTED,\n ),\n );\n } else {\n resolve(code ?? ExitCode.GENERAL_ERROR);\n }\n });\n\n geminiProcess.on('error', (error) => {\n reject(new GeminiSDKError('Gemini CLI process error', undefined, error));\n });\n });\n\n // Handle exit code\n if (exitCode !== ExitCode.SUCCESS) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n `Gemini CLI exited with code ${exitCode}${stderrOutput ? `\\n${stderrOutput}` : ''}`,\n exitCode as ExitCode,\n { stderr: stderrOutput },\n );\n }\n\n // If no events were yielded, something went wrong\n if (!hasYieldedEvents) {\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n throw new GeminiSDKError(\n 'No events received from Gemini CLI',\n undefined,\n { stderr: stderrOutput },\n );\n }\n}\n","/**\n * Gemini CLI Client\n *\n * High-level client for interacting with Gemini CLI\n */\n\nimport { EventEmitter } from 'events';\nimport { query } from './query';\nimport type {\n GeminiOptions,\n JsonStreamEvent,\n QueryResult,\n ToolResultEvent,\n} from './types';\nimport { JsonStreamEventType, ProcessStatus } from './types';\n\n/**\n * Gemini CLI Client\n *\n * Provides a high-level API for interacting with Gemini CLI\n *\n * @example\n * ```typescript\n * import { GeminiClient } from '@google/gemini-cli-sdk';\n *\n * const client = new GeminiClient({\n * pathToGeminiCLI: './node_modules/@google/gemini-cli/bundle/gemini.js',\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-2.0-flash-exp',\n * });\n *\n * // Stream events\n * for await (const event of client.stream('Hello, Gemini!')) {\n * if (event.type === 'message' && event.role === 'assistant' && event.delta) {\n * process.stdout.write(event.content);\n * }\n * }\n *\n * // Or get complete result\n * const result = await client.query('Explain TypeScript generics');\n * console.log(result.response);\n * ```\n */\nexport class GeminiClient extends EventEmitter {\n private status: ProcessStatus = ProcessStatus.IDLE;\n private currentSessionId: string | null = null;\n\n constructor(private options: GeminiOptions) {\n super();\n }\n\n /**\n * Stream events from Gemini CLI\n *\n * @param prompt - User prompt\n * @returns AsyncGenerator<JsonStreamEvent> - Stream of JSON events\n */\n async *stream(prompt: string): AsyncGenerator<JsonStreamEvent> {\n this.status = ProcessStatus.RUNNING;\n this.emit('status', this.status);\n\n try {\n for await (const event of query(prompt, this.options)) {\n // Track session ID\n if (event.type === JsonStreamEventType.INIT) {\n this.currentSessionId = event.session_id;\n this.emit('session', event.session_id);\n }\n\n // Handle permission request for tool execution\n if (event.type === JsonStreamEventType.TOOL_USE && this.options.onPermissionRequest) {\n const permissionRequest = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n timestamp: event.timestamp,\n };\n\n try {\n const decision = await this.options.onPermissionRequest(permissionRequest);\n\n // Emit permission decision event\n this.emit('permission', {\n request: permissionRequest,\n decision,\n });\n\n // Note: Since Gemini CLI has already executed the tool (approvalMode handling),\n // we can only log the decision here. To actually prevent execution,\n // use approvalMode='default' and handle stdin/stdout interaction.\n if (!decision.approved) {\n this.emit('warning', {\n type: JsonStreamEventType.ERROR,\n severity: 'warning',\n message: `Tool ${event.tool_name} was denied by permission callback but may have already executed`,\n timestamp: new Date().toISOString(),\n });\n }\n } catch (error) {\n this.emit('error', {\n message: `Permission callback error for tool ${event.tool_name}`,\n error,\n });\n // Continue processing even if permission callback fails\n }\n }\n\n // Emit event\n this.emit('event', event);\n\n // Yield to caller\n yield event;\n\n // Handle final result\n if (event.type === JsonStreamEventType.RESULT) {\n this.status =\n event.status === 'success' ? ProcessStatus.COMPLETED : ProcessStatus.ERROR;\n this.emit('status', this.status);\n }\n }\n } catch (error) {\n this.status = ProcessStatus.ERROR;\n this.emit('status', this.status);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Query Gemini CLI and return complete result\n *\n * @param prompt - User prompt\n * @returns Promise<QueryResult> - Complete query result\n */\n async query(prompt: string): Promise<QueryResult> {\n const result: QueryResult = {\n sessionId: '',\n model: '',\n response: '',\n toolCalls: [],\n status: 'success',\n };\n\n const toolCallsMap = new Map<\n string,\n {\n tool_name: string;\n tool_id: string;\n parameters: Record<string, unknown>;\n result?: ToolResultEvent;\n }\n >();\n\n for await (const event of this.stream(prompt)) {\n switch (event.type) {\n case JsonStreamEventType.INIT:\n result.sessionId = event.session_id;\n result.model = event.model;\n break;\n\n case JsonStreamEventType.MESSAGE:\n if (event.role === 'assistant') {\n result.response += event.content;\n }\n break;\n\n case JsonStreamEventType.TOOL_USE:\n toolCallsMap.set(event.tool_id, {\n tool_name: event.tool_name,\n tool_id: event.tool_id,\n parameters: event.parameters,\n });\n break;\n\n case JsonStreamEventType.TOOL_RESULT:\n {\n const toolCall = toolCallsMap.get(event.tool_id);\n if (toolCall) {\n toolCall.result = event;\n result.toolCalls.push({\n tool_name: toolCall.tool_name,\n tool_id: toolCall.tool_id,\n parameters: toolCall.parameters,\n result: {\n status: event.status,\n output: event.output,\n error: event.error,\n },\n });\n }\n }\n break;\n\n case JsonStreamEventType.RESULT:\n result.status = event.status;\n result.stats = event.stats;\n if (event.error) {\n result.error = event.error;\n }\n break;\n\n case JsonStreamEventType.ERROR:\n // Log errors but don't fail the query\n this.emit('warning', event);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Get current process status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.currentSessionId;\n }\n\n /**\n * Update options\n */\n setOptions(options: Partial<GeminiOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Get current options\n */\n getOptions(): Readonly<GeminiOptions> {\n return { ...this.options };\n }\n}\n","/**\n * GeminiStreamClient - Persistent stream-based client for Gemini CLI\n *\n * Architecture:\n * - 1 Client = 1 Node.js Process = 1 Session\n * - Communication via stdin/stdout JSONL\n * - Process stays alive for multiple message exchanges\n * - Similar to Claude Agent SDK's SubprocessCLITransport\n */\n\nimport { EventEmitter } from 'node:events';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Writable } from 'node:stream';\nimport {\n GeminiStreamOptions,\n JsonStreamEvent,\n JsonStreamEventType,\n JsonInputMessage,\n JsonInputMessageType,\n InitEvent,\n GeminiSDKError,\n ProcessStatus,\n} from './types.js';\n\n/**\n * Events emitted by GeminiStreamClient\n */\nexport interface StreamClientEvents {\n /** JSON stream event from CLI */\n event: (event: JsonStreamEvent) => void;\n\n /** Process started */\n started: () => void;\n\n /** Process ready (INIT event received) */\n ready: (initEvent: InitEvent) => void;\n\n /** Process stopped */\n stopped: (code: number | null) => void;\n\n /** Error occurred */\n error: (error: Error) => void;\n}\n\nexport declare interface GeminiStreamClient {\n on<K extends keyof StreamClientEvents>(event: K, listener: StreamClientEvents[K]): this;\n emit<K extends keyof StreamClientEvents>(event: K, ...args: Parameters<StreamClientEvents[K]>): boolean;\n}\n\n/**\n * GeminiStreamClient\n *\n * Manages a persistent Gemini CLI process for stream-based communication.\n *\n * @example\n * ```typescript\n * const client = new GeminiStreamClient({\n * pathToGeminiCLI: './gemini.js',\n * sessionId: 'session-123',\n * apiKey: process.env.GEMINI_API_KEY,\n * });\n *\n * client.on('event', (event) => {\n * console.log('Event:', event);\n * });\n *\n * await client.start();\n * await client.sendMessage('Hello, Gemini!');\n * await client.stop();\n * ```\n */\nexport class GeminiStreamClient extends EventEmitter {\n private process: ChildProcess | null = null;\n private stdinStream: Writable | null = null;\n private readlineInterface: readline.Interface | null = null;\n private status: ProcessStatus = ProcessStatus.IDLE;\n private initEvent: InitEvent | null = null;\n private initTimeout: NodeJS.Timeout | null = null;\n private tempSettingsPath: string | null = null;\n\n constructor(private options: GeminiStreamOptions) {\n super();\n\n // Validate required options\n if (!options.pathToGeminiCLI) {\n throw new GeminiSDKError('pathToGeminiCLI is required');\n }\n if (!options.sessionId) {\n throw new GeminiSDKError('sessionId is required');\n }\n }\n\n /**\n * Start the Gemini CLI process\n */\n async start(): Promise<void> {\n if (this.process) {\n throw new GeminiSDKError('Process already started');\n }\n\n this.status = ProcessStatus.RUNNING;\n\n // Create temporary settings.json if hooks or mcpServers are configured\n if (this.options.hooks || this.options.mcpServers) {\n await this.createTempSettings();\n }\n\n // Build command arguments\n const args = this.buildCommand();\n\n // Build environment variables\n const env = this.buildEnv();\n\n // Use custom Node.js path if provided, otherwise default to 'node'\n const nodeExecutable = this.options.pathToNode || 'node';\n\n // Spawn process\n this.process = spawn(nodeExecutable, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: this.options.cwd || process.cwd(),\n env,\n });\n\n // Handle process events\n this.process.on('exit', (code, signal) => {\n this.handleProcessExit(code, signal);\n });\n\n this.process.on('error', (error) => {\n this.handleProcessError(error);\n });\n\n // Setup stdin stream\n if (this.process.stdin) {\n this.stdinStream = this.process.stdin;\n // CRITICAL: Set encoding to prevent stdin from auto-closing\n this.stdinStream.setDefaultEncoding('utf-8');\n // IMPORTANT: Don't end stdin prematurely - keep it alive\n // The readline loop in CLI will wait for messages\n } else {\n throw new GeminiSDKError('Failed to get stdin stream');\n }\n\n // Setup stdout readline interface\n if (this.process.stdout) {\n this.readlineInterface = readline.createInterface({\n input: this.process.stdout,\n terminal: false, // CRITICAL: Non-terminal mode for JSONL\n });\n\n // Start reading events\n this.startReadLoop();\n } else {\n throw new GeminiSDKError('Failed to get stdout stream');\n }\n\n // Handle stderr (always process to prevent mixing with stdout)\n if (this.process.stderr) {\n this.process.stderr.on('data', (chunk) => {\n // Only log in debug mode, but always consume stderr\n if (this.options.debug) {\n console.error('[GeminiStreamClient] stderr:', chunk.toString());\n }\n });\n }\n\n this.emit('started');\n\n // Wait for INIT event\n await this.waitForInit();\n }\n\n /**\n * Send a user message to the CLI\n * @param content - User message content\n * @param temporarySystemInstruction - Optional temporary system instruction to append for this request only\n */\n async sendMessage(content: string, temporarySystemInstruction?: 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 temporary_system_instruction: temporarySystemInstruction,\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 * Truncate chat history from a specific index\n *\n * This sends a control message to the CLI to:\n * 1. Truncate in-memory history (via GeminiChat.setHistory())\n * 2. Sync to session.json file (via ChatRecordingService)\n *\n * Used for edit/retry functionality where subsequent messages need to be discarded.\n *\n * @param fromIndex - Index from which to truncate (0-based, inclusive)\n */\n async truncateHistory(fromIndex: number): Promise<void> {\n if (!this.isReady()) {\n throw new GeminiSDKError('Client not ready. Call start() first.');\n }\n\n if (fromIndex < 0) {\n throw new GeminiSDKError('fromIndex must be non-negative');\n }\n\n const message: JsonInputMessage = {\n type: JsonInputMessageType.CONTROL,\n control: {\n subtype: 'truncate_history',\n fromIndex,\n },\n session_id: this.options.sessionId,\n };\n\n this.writeMessage(message);\n }\n\n /**\n * Stop the CLI process\n */\n async stop(timeout: number = 5000): Promise<void> {\n if (!this.process) {\n return;\n }\n\n // Clear init timeout if exists\n if (this.initTimeout) {\n clearTimeout(this.initTimeout);\n this.initTimeout = null;\n }\n\n // Close stdin to signal graceful shutdown\n if (this.stdinStream) {\n this.stdinStream.end();\n this.stdinStream = null;\n }\n\n // Close readline interface\n if (this.readlineInterface) {\n this.readlineInterface.close();\n this.readlineInterface = null;\n }\n\n // Wait for process to exit (with timeout)\n await Promise.race([\n new Promise<void>((resolve) => {\n if (this.process) {\n this.process.once('exit', () => resolve());\n } else {\n resolve();\n }\n }),\n new Promise<void>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n // Force kill if still running\n if (this.process && !this.process.killed) {\n this.process.kill('SIGTERM');\n\n // Wait a bit more\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // SIGKILL if still not dead\n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n }\n\n this.process = null;\n this.status = ProcessStatus.COMPLETED;\n\n // Clean up temporary settings file\n if (this.tempSettingsPath) {\n try {\n fs.unlinkSync(this.tempSettingsPath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Cleaned up temp settings:', this.tempSettingsPath);\n }\n } catch (error) {\n console.error('[GeminiStreamClient] Failed to clean up temp settings:', error);\n }\n this.tempSettingsPath = null;\n }\n }\n\n /**\n * Check if client is ready to send messages\n */\n isReady(): boolean {\n return this.status === ProcessStatus.RUNNING && this.initEvent !== null;\n }\n\n /**\n * Get current status\n */\n getStatus(): ProcessStatus {\n return this.status;\n }\n\n /**\n * Get init event (contains session_id, model, etc.)\n */\n getInitEvent(): InitEvent | null {\n return this.initEvent;\n }\n\n /**\n * Get process PID\n */\n getPid(): number | undefined {\n return this.process?.pid;\n }\n\n /**\n * Create settings.json in GEMINI_CONFIG_DIR for hooks and MCP servers configuration\n *\n * Note: Gemini CLI does not support --settings-file parameter.\n * Instead, it loads settings from GEMINI_CONFIG_DIR/settings.json\n * where GEMINI_CONFIG_DIR is set via environment variable.\n */\n private async createTempSettings(): Promise<void> {\n // Get GEMINI_CONFIG_DIR from options.env\n const geminiConfigDir = this.options.env?.GEMINI_CONFIG_DIR;\n\n if (!geminiConfigDir) {\n throw new GeminiSDKError(\n 'GEMINI_CONFIG_DIR is required in options.env when using hooks or mcpServers. ' +\n 'Please set options.env.GEMINI_CONFIG_DIR to a directory path.'\n );\n }\n\n // Ensure the directory exists\n if (!fs.existsSync(geminiConfigDir)) {\n fs.mkdirSync(geminiConfigDir, { recursive: true });\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Created config directory:', geminiConfigDir);\n }\n }\n\n // Write settings.json to GEMINI_CONFIG_DIR\n this.tempSettingsPath = path.join(geminiConfigDir, 'settings.json');\n\n // Build settings object\n const settings: Record<string, unknown> = {};\n\n // Add hooks configuration if provided\n if (this.options.hooks) {\n settings.tools = {\n enableHooks: true,\n };\n settings.hooks = this.options.hooks;\n }\n\n // Add MCP servers configuration if provided\n if (this.options.mcpServers) {\n settings.mcpServers = this.options.mcpServers;\n }\n\n try {\n fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Wrote settings to:', this.tempSettingsPath);\n console.log('[GeminiStreamClient] Settings content:', JSON.stringify(settings, null, 2));\n }\n } catch (error) {\n throw new GeminiSDKError(`Failed to write settings file: ${error}`);\n }\n }\n\n /**\n * Build CLI command arguments\n */\n private buildCommand(): string[] {\n const args = [\n this.options.pathToGeminiCLI,\n '--stream-json-input', // ← New flag we'll add to CLI\n '--output-format',\n 'stream-json',\n ];\n\n // Note: Do NOT use --settings-file as it's not supported by Gemini CLI\n // Settings are loaded from GEMINI_CONFIG_DIR/settings.json instead\n\n // Resume from previous session file\n if (this.options.resumeSessionFilePath) {\n args.push('--resume-from-file', this.options.resumeSessionFilePath);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Resuming from session file:', this.options.resumeSessionFilePath);\n }\n }\n\n // Model\n if (this.options.model) {\n args.push('--model', this.options.model);\n }\n\n // Approval mode\n if (this.options.approvalMode) {\n args.push('--approval-mode', this.options.approvalMode);\n }\n\n // Debug mode\n if (this.options.debug) {\n args.push('--debug');\n }\n\n return args;\n }\n\n /**\n * Build environment variables\n */\n private buildEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...this.options.env,\n };\n\n // Set API key if provided\n if (this.options.apiKey) {\n // For Vertex AI mode, use GOOGLE_API_KEY\n // For Google AI Studio, use GEMINI_API_KEY\n const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === 'true';\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - API Key prefix:', this.options.apiKey.substring(0, 3));\n console.log('[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:', this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);\n console.log('[GeminiStreamClient] buildEnv() - useVertexAI:', useVertexAI);\n }\n\n if (useVertexAI) {\n env.GOOGLE_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI');\n }\n } else {\n env.GEMINI_API_KEY = this.options.apiKey;\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio');\n }\n }\n }\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:', !!env.GOOGLE_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:', !!env.GEMINI_API_KEY);\n console.log('[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:', env.GOOGLE_GENAI_USE_VERTEXAI);\n }\n\n return env;\n }\n\n /**\n * Write a JSON message to stdin\n */\n private writeMessage(message: JsonInputMessage): void {\n if (!this.stdinStream) {\n throw new GeminiSDKError('stdin stream not available');\n }\n\n const json = JSON.stringify(message);\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Writing message to stdin:', json.substring(0, 100));\n }\n\n const success = this.stdinStream.write(json + '\\n', (error) => {\n if (error) {\n console.error('[GeminiStreamClient] Write error:', error);\n } else if (this.options.debug) {\n console.log('[GeminiStreamClient] Write callback: message flushed to stdin');\n }\n });\n\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Write success:', success, 'Stream writable:', this.stdinStream.writable);\n }\n }\n\n /**\n * Start reading JSONL events from stdout\n */\n private startReadLoop(): void {\n if (!this.readlineInterface) {\n return;\n }\n\n this.readlineInterface.on('line', (line) => {\n const trimmed = line.trim();\n if (!trimmed) {\n return;\n }\n\n // Skip debug output lines (e.g., [MESSAGE_BUS], [PolicyEngine], etc.)\n if (trimmed.startsWith('[')) {\n if (this.options.debug) {\n console.log('[GeminiStreamClient] Skipping debug output:', trimmed.substring(0, 100));\n }\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