From 35907057ad74bd7bbdfbd47daaa3ff83dde4606c Mon Sep 17 00:00:00 2001 From: Coco Sheng Date: Fri, 10 Apr 2026 17:20:26 -0400 Subject: [PATCH] chore: switch from keytar to @github/keytar (#25143) --- esbuild.config.js | 2 +- package-lock.json | 52 ++++++++----------- package.json | 2 +- packages/core/package.json | 2 +- .../core/src/services/keychainService.test.ts | 2 +- packages/core/src/services/keychainService.ts | 8 +-- packages/core/src/services/keychainTypes.ts | 2 +- 7 files changed, 32 insertions(+), 38 deletions(-) diff --git a/esbuild.config.js b/esbuild.config.js index ee1f722f4b..983ca263c2 100644 --- a/esbuild.config.js +++ b/esbuild.config.js @@ -62,7 +62,7 @@ const external = [ '@lydell/node-pty-linux-x64', '@lydell/node-pty-win32-arm64', '@lydell/node-pty-win32-x64', - 'keytar', + '@github/keytar', '@google/gemini-cli-devtools', ]; diff --git a/package-lock.json b/package-lock.json index a206622594..0c6c449d32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,13 +74,13 @@ "node": ">=20.0.0" }, "optionalDependencies": { + "@github/keytar": "^7.10.6", "@lydell/node-pty": "1.1.0", "@lydell/node-pty-darwin-arm64": "1.1.0", "@lydell/node-pty-darwin-x64": "1.1.0", "@lydell/node-pty-linux-x64": "1.1.0", "@lydell/node-pty-win32-arm64": "1.1.0", "@lydell/node-pty-win32-x64": "1.1.0", - "keytar": "^7.9.0", "node-pty": "^1.0.0" } }, @@ -1099,6 +1099,27 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@github/keytar": { + "version": "7.10.6", + "resolved": "https://registry.npmjs.org/@github/keytar/-/keytar-7.10.6.tgz", + "integrity": "sha512-mRW6cUsSG+nj4jp5gp8e91zPySaT73r+2JM6VyMZfrEgksjPmjSMr+tPGNOK3HUHV+GUU9B1LAiiYy/wmAnIxA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.3.0" + } + }, + "node_modules/@github/keytar/node_modules/node-addon-api": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", + "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, "node_modules/@google-cloud/common": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz", @@ -11198,26 +11219,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/keytar": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", - "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "node-addon-api": "^4.3.0", - "prebuild-install": "^7.0.1" - } - }, - "node_modules/keytar/node_modules/prebuild-install": { - "name": "nop", - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nop/-/nop-1.0.0.tgz", - "integrity": "sha512-XdkOuXGx0DTwlqb0DWTcDqelgU/F3YyZ+PTRaecpDVpkYskcnh3OeUYKfvjcRQ2D1diTIGxi/a3eHVjW5yPupQ==", - "license": "MIT", - "optional": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -12240,13 +12241,6 @@ "node": ">= 0.4.0" } }, - "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "license": "MIT", - "optional": true - }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -18230,13 +18224,13 @@ "node": ">=20" }, "optionalDependencies": { + "@github/keytar": "^7.10.6", "@lydell/node-pty": "1.1.0", "@lydell/node-pty-darwin-arm64": "1.1.0", "@lydell/node-pty-darwin-x64": "1.1.0", "@lydell/node-pty-linux-x64": "1.1.0", "@lydell/node-pty-win32-arm64": "1.1.0", "@lydell/node-pty-win32-x64": "1.1.0", - "keytar": "^7.9.0", "node-pty": "^1.0.0" } }, diff --git a/package.json b/package.json index 0af6a9aad0..150abcf3c3 100644 --- a/package.json +++ b/package.json @@ -150,13 +150,13 @@ "simple-git": "^3.28.0" }, "optionalDependencies": { + "@github/keytar": "^7.10.6", "@lydell/node-pty": "1.1.0", "@lydell/node-pty-darwin-arm64": "1.1.0", "@lydell/node-pty-darwin-x64": "1.1.0", "@lydell/node-pty-linux-x64": "1.1.0", "@lydell/node-pty-win32-arm64": "1.1.0", "@lydell/node-pty-win32-x64": "1.1.0", - "keytar": "^7.9.0", "node-pty": "^1.0.0" }, "lint-staged": { diff --git a/packages/core/package.json b/packages/core/package.json index 53619d94c7..90010084f7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -91,13 +91,13 @@ "zod-to-json-schema": "^3.25.1" }, "optionalDependencies": { + "@github/keytar": "^7.10.6", "@lydell/node-pty": "1.1.0", "@lydell/node-pty-darwin-arm64": "1.1.0", "@lydell/node-pty-darwin-x64": "1.1.0", "@lydell/node-pty-linux-x64": "1.1.0", "@lydell/node-pty-win32-arm64": "1.1.0", "@lydell/node-pty-win32-x64": "1.1.0", - "keytar": "^7.9.0", "node-pty": "^1.0.0" }, "devDependencies": { diff --git a/packages/core/src/services/keychainService.test.ts b/packages/core/src/services/keychainService.test.ts index 6b1fd9fbf2..7649271a02 100644 --- a/packages/core/src/services/keychainService.test.ts +++ b/packages/core/src/services/keychainService.test.ts @@ -42,7 +42,7 @@ const mockFileKeychain: MockKeychain = { findCredentials: vi.fn(), }; -vi.mock('keytar', () => ({ default: mockKeytar })); +vi.mock('@github/keytar', () => ({ default: mockKeytar })); vi.mock('./fileKeychain.js', () => ({ FileKeychain: vi.fn(() => mockFileKeychain), diff --git a/packages/core/src/services/keychainService.ts b/packages/core/src/services/keychainService.ts index e7f5a54743..89ec0dd662 100644 --- a/packages/core/src/services/keychainService.ts +++ b/packages/core/src/services/keychainService.ts @@ -22,7 +22,7 @@ import { FileKeychain } from './fileKeychain.js'; export const FORCE_FILE_STORAGE_ENV_VAR = 'GEMINI_FORCE_FILE_STORAGE'; /** - * Service for interacting with OS-level secure storage (e.g. keytar). + * Service for interacting with OS-level secure storage (e.g. @github/keytar). */ export class KeychainService { // Track an ongoing initialization attempt to avoid race conditions. @@ -119,7 +119,7 @@ export class KeychainService { } /** - * Attempts to load and verify the native keychain module (keytar). + * Attempts to load and verify the native keychain module (@github/keytar). */ private async getNativeKeychain(): Promise { try { @@ -152,7 +152,7 @@ export class KeychainService { // Low-level dynamic loading and structural validation. private async loadKeychainModule(): Promise { - const moduleName = 'keytar'; + const moduleName = '@github/keytar'; const module: unknown = await import(moduleName); const potential = (isRecord(module) && module['default']) || module; @@ -189,7 +189,7 @@ export class KeychainService { */ private isMacOSKeychainAvailable(): boolean { // Probing via the `security` CLI avoids a blocking OS-level popup that - // occurs when calling keytar without a configured keychain. + // occurs when calling @github/keytar without a configured keychain. const result = spawnSync('security', ['default-keychain'], { encoding: 'utf8', // We pipe stdout to read the path, but ignore stderr to suppress diff --git a/packages/core/src/services/keychainTypes.ts b/packages/core/src/services/keychainTypes.ts index a643f763e4..40c486bac0 100644 --- a/packages/core/src/services/keychainTypes.ts +++ b/packages/core/src/services/keychainTypes.ts @@ -8,7 +8,7 @@ import { z } from 'zod'; /** * Interface for OS-level secure storage operations. - * Note: Method names must match the underlying library (e.g. keytar) + * Note: Method names must match the underlying library (e.g. @github/keytar) * to support correct dynamic loading and schema validation. */ export interface Keychain {