






















@@ -749,6 +749,68 @@ describe("shouldSkipLocalCliCredentialEpoch", () => {
749749}
750750});
751751752+it("cleans generated Gemini MCP settings when auth preparation fails", async () => {
753+const { dir, sessionFile } = createSessionFile();
754+let generatedSystemSettingsPath: string | undefined;
755+const getActiveMcpLoopbackRuntime = vi.fn(() => ({
756+port: 31783,
757+ownerToken: "loopback-owner-token",
758+nonOwnerToken: "loopback-non-owner-token",
759+}));
760+const prepareExecution = vi.fn(async (ctx: { env?: Record<string, string> }) => {
761+generatedSystemSettingsPath = ctx.env?.GEMINI_CLI_SYSTEM_SETTINGS_PATH;
762+throw new Error("Gemini auth profile was selected but no credential material was found");
763+});
764+cliBackendsTesting.setDepsForTest({
765+resolvePluginSetupCliBackend: () => undefined,
766+resolveRuntimeCliBackends: () => [
767+{
768+id: "google-gemini-cli",
769+pluginId: "google",
770+bundleMcp: true,
771+bundleMcpMode: "gemini-system-settings",
772+ prepareExecution,
773+config: {
774+command: "gemini",
775+args: ["--prompt", "{prompt}"],
776+output: "json",
777+input: "arg",
778+sessionMode: "existing",
779+},
780+},
781+],
782+});
783+setCliRunnerPrepareTestDeps({
784+ getActiveMcpLoopbackRuntime,
785+ensureMcpLoopbackServer: vi.fn(createTestMcpLoopbackServer),
786+createMcpLoopbackServerConfig: vi.fn(createTestMcpLoopbackServerConfig),
787+resolveMcpLoopbackBearerToken: vi.fn(() => "loopback-token"),
788+resolveMcpLoopbackScopedTools: vi.fn(() => ({ agentId: "main", tools: [] })),
789+});
790+791+try {
792+await expect(
793+prepareCliRunContext({
794+sessionId: "session-test",
795+sessionKey: "agent:main:main",
796+ sessionFile,
797+workspaceDir: dir,
798+prompt: "latest ask",
799+provider: "google-gemini-cli",
800+model: "gemini-3.1-pro-preview",
801+timeoutMs: 1_000,
802+runId: "run-test-gemini-mcp-cleanup-on-auth-failure",
803+config: {},
804+}),
805+).rejects.toThrow(/no credential material/);
806+807+expect(generatedSystemSettingsPath).toBeTruthy();
808+expect(fs.existsSync(generatedSystemSettingsPath ?? "")).toBe(false);
809+} finally {
810+fs.rmSync(dir, { recursive: true, force: true });
811+}
812+});
813+752814it("prepares side questions without agent-turn context, tools, hooks, or reusable sessions", async () => {
753815const { dir, sessionFile } = createSessionFile();
754816appendTranscriptEntry(sessionFile, {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。