refactor(google): merge gemini auth into google plugin

This commit is contained in:
Peter Steinberger 2026-03-16 01:13:17 +00:00
parent d56559bad7
commit bc5054ce68
30 changed files with 200 additions and 291 deletions

View File

@ -176,16 +176,13 @@ OpenClaw ships with the piai catalog. These providers require **no**
- Compatibility: legacy OpenClaw config using `google/gemini-3.1-flash-preview` is normalized to `google/gemini-3-flash-preview`
- CLI: `openclaw onboard --auth-choice gemini-api-key`
### Google Vertex, Antigravity, and Gemini CLI
### Google Vertex and Gemini CLI
- Providers: `google-vertex`, `google-antigravity`, `google-gemini-cli`
- Auth: Vertex uses gcloud ADC; Antigravity/Gemini CLI use their respective auth flows
- Caution: Antigravity and Gemini CLI OAuth in OpenClaw are unofficial integrations. Some users have reported Google account restrictions after using third-party clients. Review Google terms and use a non-critical account if you choose to proceed.
- Antigravity OAuth is shipped as a bundled plugin (`google-antigravity-auth`, disabled by default).
- Enable: `openclaw plugins enable google-antigravity-auth`
- Login: `openclaw models auth login --provider google-antigravity --set-default`
- Gemini CLI OAuth is shipped as a bundled plugin (`google-gemini-cli-auth`, disabled by default).
- Enable: `openclaw plugins enable google-gemini-cli-auth`
- Providers: `google-vertex`, `google-gemini-cli`
- Auth: Vertex uses gcloud ADC; Gemini CLI uses its OAuth flow
- Caution: Gemini CLI OAuth in OpenClaw is an unofficial integration. Some users have reported Google account restrictions after using third-party clients. Review Google terms and use a non-critical account if you choose to proceed.
- Gemini CLI OAuth is shipped as part of the bundled `google` plugin.
- Enable: `openclaw plugins enable google`
- Login: `openclaw models auth login --provider google-gemini-cli --set-default`
- Note: you do **not** paste a client id or secret into `openclaw.json`. The CLI login flow stores
tokens in auth profiles on the gateway host.

View File

@ -783,7 +783,7 @@ Gemini CLI uses a **plugin auth flow**, not a client id or secret in `openclaw.j
Steps:
1. Enable the plugin: `openclaw plugins enable google-gemini-cli-auth`
1. Enable the plugin: `openclaw plugins enable google`
2. Login: `openclaw models auth login --provider google-gemini-cli --set-default`
This stores OAuth tokens in auth profiles on the gateway host. Details: [Model providers](/concepts/model-providers).

View File

@ -167,8 +167,7 @@ Important trust note:
- Anthropic provider runtime — bundled as `anthropic` (enabled by default)
- BytePlus provider catalog — bundled as `byteplus` (enabled by default)
- Cloudflare AI Gateway provider catalog — bundled as `cloudflare-ai-gateway` (enabled by default)
- Google Antigravity OAuth (provider auth) — bundled as `google-antigravity-auth` (disabled by default)
- Gemini CLI OAuth (provider auth) — bundled as `google-gemini-cli-auth` (disabled by default)
- Google web search + Gemini CLI OAuth — bundled as `google` (web search auto-loads it; provider auth stays opt-in)
- GitHub Copilot provider runtime — bundled as `github-copilot` (enabled by default)
- Hugging Face provider catalog — bundled as `huggingface` (enabled by default)
- Kilo Gateway provider runtime — bundled as `kilocode` (enabled by default)
@ -521,8 +520,7 @@ authoring plugins:
`openclaw/plugin-sdk/acpx`, `openclaw/plugin-sdk/bluebubbles`,
`openclaw/plugin-sdk/copilot-proxy`, `openclaw/plugin-sdk/device-pair`,
`openclaw/plugin-sdk/diagnostics-otel`, `openclaw/plugin-sdk/diffs`,
`openclaw/plugin-sdk/feishu`,
`openclaw/plugin-sdk/google-gemini-cli-auth`, `openclaw/plugin-sdk/googlechat`,
`openclaw/plugin-sdk/feishu`, `openclaw/plugin-sdk/googlechat`,
`openclaw/plugin-sdk/irc`, `openclaw/plugin-sdk/llm-task`,
`openclaw/plugin-sdk/lobster`, `openclaw/plugin-sdk/matrix`,
`openclaw/plugin-sdk/mattermost`, `openclaw/plugin-sdk/memory-core`,

View File

@ -1,41 +0,0 @@
# Google Gemini CLI Auth (OpenClaw plugin)
OAuth provider plugin for **Gemini CLI** (Google Code Assist).
## Account safety caution
- This plugin is an unofficial integration and is not endorsed by Google.
- Some users have reported account restrictions or suspensions after using third-party Gemini CLI and Antigravity OAuth clients.
- Use caution, review the applicable Google terms, and avoid using a mission-critical account.
## Enable
Bundled plugins are disabled by default. Enable this one:
```bash
openclaw plugins enable google-gemini-cli-auth
```
Restart the Gateway after enabling.
## Authenticate
```bash
openclaw models auth login --provider google-gemini-cli --set-default
```
## Requirements
Requires the Gemini CLI to be installed (credentials are extracted automatically):
```bash
brew install gemini-cli
# or: npm install -g @google/gemini-cli
```
## Env vars (optional)
Override auto-detected credentials with:
- `OPENCLAW_GEMINI_OAUTH_CLIENT_ID` / `GEMINI_CLI_OAUTH_CLIENT_ID`
- `OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET` / `GEMINI_CLI_OAUTH_CLIENT_SECRET`

View File

@ -1,158 +0,0 @@
import {
buildOauthProviderAuthResult,
emptyPluginConfigSchema,
type ProviderFetchUsageSnapshotContext,
type OpenClawPluginApi,
type ProviderAuthContext,
type ProviderResolveDynamicModelContext,
type ProviderRuntimeModel,
} from "openclaw/plugin-sdk/google-gemini-cli-auth";
import { normalizeModelCompat } from "../../src/agents/model-compat.js";
import { fetchGeminiUsage } from "../../src/infra/provider-usage.fetch.js";
import { loginGeminiCliOAuth } from "./oauth.js";
const PROVIDER_ID = "google-gemini-cli";
const PROVIDER_LABEL = "Gemini CLI OAuth";
const DEFAULT_MODEL = "google-gemini-cli/gemini-3.1-pro-preview";
const GEMINI_3_1_PRO_PREFIX = "gemini-3.1-pro";
const GEMINI_3_1_FLASH_PREFIX = "gemini-3.1-flash";
const GEMINI_3_1_PRO_TEMPLATE_IDS = ["gemini-3-pro-preview"] as const;
const GEMINI_3_1_FLASH_TEMPLATE_IDS = ["gemini-3-flash-preview"] as const;
const ENV_VARS = [
"OPENCLAW_GEMINI_OAUTH_CLIENT_ID",
"OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET",
"GEMINI_CLI_OAUTH_CLIENT_ID",
"GEMINI_CLI_OAUTH_CLIENT_SECRET",
];
function cloneFirstTemplateModel(params: {
modelId: string;
templateIds: readonly string[];
ctx: ProviderResolveDynamicModelContext;
}): ProviderRuntimeModel | undefined {
const trimmedModelId = params.modelId.trim();
for (const templateId of [...new Set(params.templateIds)].filter(Boolean)) {
const template = params.ctx.modelRegistry.find(
PROVIDER_ID,
templateId,
) as ProviderRuntimeModel | null;
if (!template) {
continue;
}
return normalizeModelCompat({
...template,
id: trimmedModelId,
name: trimmedModelId,
reasoning: true,
} as ProviderRuntimeModel);
}
return undefined;
}
function parseGoogleUsageToken(apiKey: string): string {
try {
const parsed = JSON.parse(apiKey) as { token?: unknown };
if (typeof parsed?.token === "string") {
return parsed.token;
}
} catch {
// ignore
}
return apiKey;
}
async function fetchGeminiCliUsage(ctx: ProviderFetchUsageSnapshotContext) {
return await fetchGeminiUsage(ctx.token, ctx.timeoutMs, ctx.fetchFn, PROVIDER_ID);
}
function resolveGeminiCliForwardCompatModel(
ctx: ProviderResolveDynamicModelContext,
): ProviderRuntimeModel | undefined {
const trimmed = ctx.modelId.trim();
const lower = trimmed.toLowerCase();
let templateIds: readonly string[];
if (lower.startsWith(GEMINI_3_1_PRO_PREFIX)) {
templateIds = GEMINI_3_1_PRO_TEMPLATE_IDS;
} else if (lower.startsWith(GEMINI_3_1_FLASH_PREFIX)) {
templateIds = GEMINI_3_1_FLASH_TEMPLATE_IDS;
} else {
return undefined;
}
return cloneFirstTemplateModel({
modelId: trimmed,
templateIds,
ctx,
});
}
const geminiCliPlugin = {
id: "google-gemini-cli-auth",
name: "Google Gemini CLI Auth",
description: "OAuth flow for Gemini CLI (Google Code Assist)",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
api.registerProvider({
id: PROVIDER_ID,
label: PROVIDER_LABEL,
docsPath: "/providers/models",
aliases: ["gemini-cli"],
envVars: ENV_VARS,
auth: [
{
id: "oauth",
label: "Google OAuth",
hint: "PKCE + localhost callback",
kind: "oauth",
run: async (ctx: ProviderAuthContext) => {
const spin = ctx.prompter.progress("Starting Gemini CLI OAuth…");
try {
const result = await loginGeminiCliOAuth({
isRemote: ctx.isRemote,
openUrl: ctx.openUrl,
log: (msg) => ctx.runtime.log(msg),
note: ctx.prompter.note,
prompt: async (message) => String(await ctx.prompter.text({ message })),
progress: spin,
});
spin.stop("Gemini CLI OAuth complete");
return buildOauthProviderAuthResult({
providerId: PROVIDER_ID,
defaultModel: DEFAULT_MODEL,
access: result.access,
refresh: result.refresh,
expires: result.expires,
email: result.email,
credentialExtra: { projectId: result.projectId },
notes: ["If requests fail, set GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_PROJECT_ID."],
});
} catch (err) {
spin.stop("Gemini CLI OAuth failed");
await ctx.prompter.note(
"Trouble with OAuth? Ensure your Google account has Gemini CLI access.",
"OAuth help",
);
throw err;
}
},
},
],
resolveDynamicModel: (ctx) => resolveGeminiCliForwardCompatModel(ctx),
resolveUsageAuth: async (ctx) => {
const auth = await ctx.resolveOAuthToken();
if (!auth) {
return null;
}
return {
...auth,
token: parseGoogleUsageToken(auth.token),
};
},
fetchUsageSnapshot: async (ctx) => await fetchGeminiCliUsage(ctx),
});
},
};
export default geminiCliPlugin;

View File

@ -1,9 +0,0 @@
{
"id": "google-gemini-cli-auth",
"providers": ["google-gemini-cli"],
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {}
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@openclaw/google-gemini-cli-auth",
"version": "2026.3.14",
"private": true,
"description": "OpenClaw Gemini CLI OAuth provider plugin",
"type": "module",
"openclaw": {
"extensions": [
"./index.ts"
]
}
}

View File

@ -4,24 +4,38 @@ import {
createProviderUsageFetch,
makeResponse,
} from "../../src/test-utils/provider-usage-fetch.js";
import geminiCliPlugin from "./index.js";
import googlePlugin from "./index.js";
function registerProvider(): ProviderPlugin {
function registerGooglePlugin(): {
provider: ProviderPlugin;
webSearchProviderRegistered: boolean;
} {
let provider: ProviderPlugin | undefined;
geminiCliPlugin.register({
let webSearchProviderRegistered = false;
googlePlugin.register({
registerProvider(nextProvider: ProviderPlugin) {
provider = nextProvider;
},
registerWebSearchProvider() {
webSearchProviderRegistered = true;
},
} as never);
if (!provider) {
throw new Error("provider registration missing");
}
return provider;
return { provider, webSearchProviderRegistered };
}
describe("google-gemini-cli-auth plugin", () => {
describe("google plugin", () => {
it("registers both Gemini CLI auth and Gemini web search", () => {
const result = registerGooglePlugin();
expect(result.provider.id).toBe("google-gemini-cli");
expect(result.webSearchProviderRegistered).toBe(true);
});
it("owns gemini 3.1 forward-compat resolution", () => {
const provider = registerProvider();
const { provider } = registerGooglePlugin();
const model = provider.resolveDynamicModel?.({
provider: "google-gemini-cli",
modelId: "gemini-3.1-pro-preview",
@ -52,7 +66,7 @@ describe("google-gemini-cli-auth plugin", () => {
});
it("owns usage-token parsing", async () => {
const provider = registerProvider();
const { provider } = registerGooglePlugin();
await expect(
provider.resolveUsageAuth?.({
config: {} as never,
@ -71,7 +85,7 @@ describe("google-gemini-cli-auth plugin", () => {
});
it("owns usage snapshot fetching", async () => {
const provider = registerProvider();
const { provider } = registerGooglePlugin();
const mockFetch = createProviderUsageFetch(async (url) => {
if (url.includes("cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota")) {
return makeResponse(200, {

View File

@ -0,0 +1,149 @@
import { normalizeModelCompat } from "../../src/agents/model-compat.js";
import { fetchGeminiUsage } from "../../src/infra/provider-usage.fetch.js";
import { buildOauthProviderAuthResult } from "../../src/plugin-sdk/provider-auth-result.js";
import type {
OpenClawPluginApi,
ProviderAuthContext,
ProviderFetchUsageSnapshotContext,
ProviderResolveDynamicModelContext,
ProviderRuntimeModel,
} from "../../src/plugins/types.js";
import { loginGeminiCliOAuth } from "./oauth.js";
const PROVIDER_ID = "google-gemini-cli";
const PROVIDER_LABEL = "Gemini CLI OAuth";
const DEFAULT_MODEL = "google-gemini-cli/gemini-3.1-pro-preview";
const GEMINI_3_1_PRO_PREFIX = "gemini-3.1-pro";
const GEMINI_3_1_FLASH_PREFIX = "gemini-3.1-flash";
const GEMINI_3_1_PRO_TEMPLATE_IDS = ["gemini-3-pro-preview"] as const;
const GEMINI_3_1_FLASH_TEMPLATE_IDS = ["gemini-3-flash-preview"] as const;
const ENV_VARS = [
"OPENCLAW_GEMINI_OAUTH_CLIENT_ID",
"OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET",
"GEMINI_CLI_OAUTH_CLIENT_ID",
"GEMINI_CLI_OAUTH_CLIENT_SECRET",
];
function cloneFirstTemplateModel(params: {
modelId: string;
templateIds: readonly string[];
ctx: ProviderResolveDynamicModelContext;
}): ProviderRuntimeModel | undefined {
const trimmedModelId = params.modelId.trim();
for (const templateId of [...new Set(params.templateIds)].filter(Boolean)) {
const template = params.ctx.modelRegistry.find(
PROVIDER_ID,
templateId,
) as ProviderRuntimeModel | null;
if (!template) {
continue;
}
return normalizeModelCompat({
...template,
id: trimmedModelId,
name: trimmedModelId,
reasoning: true,
} as ProviderRuntimeModel);
}
return undefined;
}
function parseGoogleUsageToken(apiKey: string): string {
try {
const parsed = JSON.parse(apiKey) as { token?: unknown };
if (typeof parsed?.token === "string") {
return parsed.token;
}
} catch {
// ignore
}
return apiKey;
}
async function fetchGeminiCliUsage(ctx: ProviderFetchUsageSnapshotContext) {
return await fetchGeminiUsage(ctx.token, ctx.timeoutMs, ctx.fetchFn, PROVIDER_ID);
}
function resolveGeminiCliForwardCompatModel(
ctx: ProviderResolveDynamicModelContext,
): ProviderRuntimeModel | undefined {
const trimmed = ctx.modelId.trim();
const lower = trimmed.toLowerCase();
let templateIds: readonly string[];
if (lower.startsWith(GEMINI_3_1_PRO_PREFIX)) {
templateIds = GEMINI_3_1_PRO_TEMPLATE_IDS;
} else if (lower.startsWith(GEMINI_3_1_FLASH_PREFIX)) {
templateIds = GEMINI_3_1_FLASH_TEMPLATE_IDS;
} else {
return undefined;
}
return cloneFirstTemplateModel({
modelId: trimmed,
templateIds,
ctx,
});
}
export function registerGoogleGeminiCliProvider(api: OpenClawPluginApi) {
api.registerProvider({
id: PROVIDER_ID,
label: PROVIDER_LABEL,
docsPath: "/providers/models",
aliases: ["gemini-cli"],
envVars: ENV_VARS,
auth: [
{
id: "oauth",
label: "Google OAuth",
hint: "PKCE + localhost callback",
kind: "oauth",
run: async (ctx: ProviderAuthContext) => {
const spin = ctx.prompter.progress("Starting Gemini CLI OAuth…");
try {
const result = await loginGeminiCliOAuth({
isRemote: ctx.isRemote,
openUrl: ctx.openUrl,
log: (msg) => ctx.runtime.log(msg),
note: ctx.prompter.note,
prompt: async (message) => String(await ctx.prompter.text({ message })),
progress: spin,
});
spin.stop("Gemini CLI OAuth complete");
return buildOauthProviderAuthResult({
providerId: PROVIDER_ID,
defaultModel: DEFAULT_MODEL,
access: result.access,
refresh: result.refresh,
expires: result.expires,
email: result.email,
credentialExtra: { projectId: result.projectId },
notes: ["If requests fail, set GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_PROJECT_ID."],
});
} catch (err) {
spin.stop("Gemini CLI OAuth failed");
await ctx.prompter.note(
"Trouble with OAuth? Ensure your Google account has Gemini CLI access.",
"OAuth help",
);
throw err;
}
},
},
],
resolveDynamicModel: (ctx) => resolveGeminiCliForwardCompatModel(ctx),
resolveUsageAuth: async (ctx) => {
const auth = await ctx.resolveOAuthToken();
if (!auth) {
return null;
}
return {
...auth,
token: parseGoogleUsageToken(auth.token),
};
},
fetchUsageSnapshot: async (ctx) => await fetchGeminiCliUsage(ctx),
});
}

View File

@ -5,6 +5,7 @@ import {
} from "../../src/agents/tools/web-search-plugin-factory.js";
import { emptyPluginConfigSchema } from "../../src/plugins/config-schema.js";
import type { OpenClawPluginApi } from "../../src/plugins/types.js";
import { registerGoogleGeminiCliProvider } from "./gemini-cli-provider.js";
const googlePlugin = {
id: "google",
@ -12,6 +13,7 @@ const googlePlugin = {
description: "Bundled Google plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
registerGoogleGeminiCliProvider(api);
api.registerWebSearchProvider(
createPluginBackedWebSearchProvider({
id: "gemini",

View File

@ -1,8 +1,11 @@
import { join, parse } from "node:path";
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
vi.mock("openclaw/plugin-sdk/google-gemini-cli-auth", () => ({
vi.mock("../../src/infra/wsl.js", () => ({
isWSL2Sync: () => false,
}));
vi.mock("../../src/infra/net/fetch-guard.js", () => ({
fetchWithSsrFGuard: async (params: {
url: string;
init?: RequestInit;

View File

@ -2,7 +2,8 @@ import { createHash, randomBytes } from "node:crypto";
import { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs";
import { createServer } from "node:http";
import { delimiter, dirname, join } from "node:path";
import { fetchWithSsrFGuard, isWSL2Sync } from "openclaw/plugin-sdk/google-gemini-cli-auth";
import { fetchWithSsrFGuard } from "../../src/infra/net/fetch-guard.js";
import { isWSL2Sync } from "../../src/infra/wsl.js";
const CLIENT_ID_KEYS = ["OPENCLAW_GEMINI_OAUTH_CLIENT_ID", "GEMINI_CLI_OAUTH_CLIENT_ID"];
const CLIENT_SECRET_KEYS = [

View File

@ -1,5 +1,6 @@
{
"id": "google",
"providers": ["google-gemini-cli"],
"configSchema": {
"type": "object",
"additionalProperties": false,

View File

@ -108,10 +108,6 @@
"types": "./dist/plugin-sdk/feishu.d.ts",
"default": "./dist/plugin-sdk/feishu.js"
},
"./plugin-sdk/google-gemini-cli-auth": {
"types": "./dist/plugin-sdk/google-gemini-cli-auth.d.ts",
"default": "./dist/plugin-sdk/google-gemini-cli-auth.js"
},
"./plugin-sdk/googlechat": {
"types": "./dist/plugin-sdk/googlechat.d.ts",
"default": "./dist/plugin-sdk/googlechat.js"

View File

@ -14,11 +14,6 @@ const allowedRawFetchCallsites = new Set([
"extensions/feishu/src/streaming-card.ts:101",
"extensions/feishu/src/streaming-card.ts:143",
"extensions/feishu/src/streaming-card.ts:199",
"extensions/google-gemini-cli-auth/oauth.ts:372",
"extensions/google-gemini-cli-auth/oauth.ts:408",
"extensions/google-gemini-cli-auth/oauth.ts:447",
"extensions/google-gemini-cli-auth/oauth.ts:507",
"extensions/google-gemini-cli-auth/oauth.ts:575",
"extensions/googlechat/src/api.ts:22",
"extensions/googlechat/src/api.ts:43",
"extensions/googlechat/src/api.ts:63",

View File

@ -59,7 +59,6 @@ const requiredSubpathEntries = [
"diagnostics-otel",
"diffs",
"feishu",
"google-gemini-cli-auth",
"googlechat",
"irc",
"llm-task",

View File

@ -57,8 +57,6 @@ const requiredPathGroups = [
"dist/plugin-sdk/diffs.d.ts",
"dist/plugin-sdk/feishu.js",
"dist/plugin-sdk/feishu.d.ts",
"dist/plugin-sdk/google-gemini-cli-auth.js",
"dist/plugin-sdk/google-gemini-cli-auth.d.ts",
"dist/plugin-sdk/googlechat.js",
"dist/plugin-sdk/googlechat.d.ts",
"dist/plugin-sdk/irc.js",

View File

@ -25,7 +25,6 @@ const entrypoints = [
"diagnostics-otel",
"diffs",
"feishu",
"google-gemini-cli-auth",
"googlechat",
"irc",
"llm-task",

View File

@ -77,7 +77,7 @@ describe("applyAuthChoiceGoogleGeminiCli", () => {
expect(result).toBe(expected);
expect(mockedApplyAuthChoicePluginProvider).toHaveBeenCalledWith(params, {
authChoice: "google-gemini-cli",
pluginId: "google-gemini-cli-auth",
pluginId: "google",
providerId: "google-gemini-cli",
methodId: "oauth",
label: "Google Gemini CLI",

View File

@ -29,7 +29,7 @@ export async function applyAuthChoiceGoogleGeminiCli(
return await applyAuthChoicePluginProvider(params, {
authChoice: "google-gemini-cli",
pluginId: "google-gemini-cli-auth",
pluginId: "google",
providerId: "google-gemini-cli",
methodId: "oauth",
label: "Google Gemini CLI",

View File

@ -307,7 +307,7 @@ describe("applyPluginAutoEnable", () => {
env: {},
});
expect(result.config.plugins?.entries?.["google-gemini-cli-auth"]?.enabled).toBe(true);
expect(result.config.plugins?.entries?.google?.enabled).toBe(true);
});
it("auto-enables acpx plugin when ACP is configured", () => {

View File

@ -28,7 +28,7 @@ export type PluginAutoEnableResult = {
};
const PROVIDER_PLUGIN_IDS: Array<{ pluginId: string; providerId: string }> = [
{ pluginId: "google-gemini-cli-auth", providerId: "google-gemini-cli" },
{ pluginId: "google", providerId: "google-gemini-cli" },
{ pluginId: "qwen-portal-auth", providerId: "qwen-portal" },
{ pluginId: "copilot-proxy", providerId: "copilot-proxy" },
{ pluginId: "minimax-portal-auth", providerId: "minimax-portal" },

View File

@ -1,15 +0,0 @@
// Narrow plugin-sdk surface for the bundled google-gemini-cli-auth plugin.
// Keep this list additive and scoped to symbols used under extensions/google-gemini-cli-auth.
export { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js";
export { isWSL2Sync } from "../infra/wsl.js";
export { emptyPluginConfigSchema } from "../plugins/config-schema.js";
export type {
OpenClawPluginApi,
ProviderAuthContext,
ProviderFetchUsageSnapshotContext,
ProviderResolveDynamicModelContext,
ProviderRuntimeModel,
} from "../plugins/types.js";
export type { ProviderUsageSnapshot } from "../infra/provider-usage.types.js";
export { buildOauthProviderAuthResult } from "./provider-auth-result.js";

View File

@ -25,7 +25,6 @@ const pluginSdkEntrypoints = [
"diagnostics-otel",
"diffs",
"feishu",
"google-gemini-cli-auth",
"googlechat",
"irc",
"llm-task",

View File

@ -18,10 +18,6 @@ const bundledExtensionSubpathLoaders = [
{ id: "diagnostics-otel", load: () => import("openclaw/plugin-sdk/diagnostics-otel") },
{ id: "diffs", load: () => import("openclaw/plugin-sdk/diffs") },
{ id: "feishu", load: () => import("openclaw/plugin-sdk/feishu") },
{
id: "google-gemini-cli-auth",
load: () => import("openclaw/plugin-sdk/google-gemini-cli-auth"),
},
{ id: "googlechat", load: () => import("openclaw/plugin-sdk/googlechat") },
{ id: "irc", load: () => import("openclaw/plugin-sdk/irc") },
{ id: "llm-task", load: () => import("openclaw/plugin-sdk/llm-task") },

View File

@ -5,9 +5,9 @@ import { enablePluginInConfig } from "./enable.js";
describe("enablePluginInConfig", () => {
it("enables a plugin entry", () => {
const cfg: OpenClawConfig = {};
const result = enablePluginInConfig(cfg, "google-gemini-cli-auth");
const result = enablePluginInConfig(cfg, "google");
expect(result.enabled).toBe(true);
expect(result.config.plugins?.entries?.["google-gemini-cli-auth"]?.enabled).toBe(true);
expect(result.config.plugins?.entries?.google?.enabled).toBe(true);
});
it("adds plugin to allowlist when allowlist is configured", () => {
@ -16,18 +16,18 @@ describe("enablePluginInConfig", () => {
allow: ["memory-core"],
},
};
const result = enablePluginInConfig(cfg, "google-gemini-cli-auth");
const result = enablePluginInConfig(cfg, "google");
expect(result.enabled).toBe(true);
expect(result.config.plugins?.allow).toEqual(["memory-core", "google-gemini-cli-auth"]);
expect(result.config.plugins?.allow).toEqual(["memory-core", "google"]);
});
it("refuses enable when plugin is denylisted", () => {
const cfg: OpenClawConfig = {
plugins: {
deny: ["google-gemini-cli-auth"],
deny: ["google"],
},
};
const result = enablePluginInConfig(cfg, "google-gemini-cli-auth");
const result = enablePluginInConfig(cfg, "google");
expect(result.enabled).toBe(false);
expect(result.reason).toBe("blocked by denylist");
});

View File

@ -10,7 +10,7 @@ const BUNDLED_PROVIDER_ALLOWLIST_COMPAT_PLUGIN_IDS = [
"cloudflare-ai-gateway",
"copilot-proxy",
"github-copilot",
"google-gemini-cli-auth",
"google",
"huggingface",
"kilocode",
"kimi-coding",

View File

@ -31,7 +31,6 @@
"src/plugin-sdk/diagnostics-otel.ts",
"src/plugin-sdk/diffs.ts",
"src/plugin-sdk/feishu.ts",
"src/plugin-sdk/google-gemini-cli-auth.ts",
"src/plugin-sdk/googlechat.ts",
"src/plugin-sdk/irc.ts",
"src/plugin-sdk/llm-task.ts",

View File

@ -77,7 +77,6 @@ const pluginSdkEntrypoints = [
"diagnostics-otel",
"diffs",
"feishu",
"google-gemini-cli-auth",
"googlechat",
"irc",
"llm-task",

View File

@ -27,7 +27,6 @@ const pluginSdkSubpaths = [
"diagnostics-otel",
"diffs",
"feishu",
"google-gemini-cli-auth",
"googlechat",
"irc",
"llm-task",