sync gemini-cli 0.1.17

Co-Authored-By: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Yiheng Xu
2025-08-05 16:44:06 +08:00
235 changed files with 16997 additions and 3736 deletions

View File

@@ -7,7 +7,6 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import * as http from 'node:http';
import * as crypto from 'node:crypto';
import open from 'open';
import {
MCPOAuthProvider,
MCPOAuthConfig,
@@ -17,7 +16,10 @@ import {
import { MCPOAuthTokenStorage, MCPOAuthToken } from './oauth-token-storage.js';
// Mock dependencies
vi.mock('open');
const mockOpenBrowserSecurely = vi.hoisted(() => vi.fn());
vi.mock('../utils/secure-browser-launcher.js', () => ({
openBrowserSecurely: mockOpenBrowserSecurely,
}));
vi.mock('node:crypto');
vi.mock('./oauth-token-storage.js');
@@ -64,6 +66,7 @@ describe('MCPOAuthProvider', () => {
beforeEach(() => {
vi.clearAllMocks();
mockOpenBrowserSecurely.mockClear();
vi.spyOn(console, 'log').mockImplementation(() => {});
vi.spyOn(console, 'warn').mockImplementation(() => {});
vi.spyOn(console, 'error').mockImplementation(() => {});
@@ -145,7 +148,9 @@ describe('MCPOAuthProvider', () => {
expiresAt: expect.any(Number),
});
expect(open).toHaveBeenCalledWith(expect.stringContaining('authorize'));
expect(mockOpenBrowserSecurely).toHaveBeenCalledWith(
expect.stringContaining('authorize'),
);
expect(MCPOAuthTokenStorage.saveToken).toHaveBeenCalledWith(
'test-server',
expect.objectContaining({ accessToken: 'access_token_123' }),
@@ -672,13 +677,10 @@ describe('MCPOAuthProvider', () => {
describe('Authorization URL building', () => {
it('should build correct authorization URL with all parameters', async () => {
// Mock to capture the URL that would be opened
let capturedUrl: string;
vi.mocked(open).mockImplementation((url) => {
let capturedUrl: string | undefined;
mockOpenBrowserSecurely.mockImplementation((url: string) => {
capturedUrl = url;
// Return a minimal mock ChildProcess
return Promise.resolve({
pid: 1234,
} as unknown as import('child_process').ChildProcess);
return Promise.resolve();
});
let callbackHandler: unknown;
@@ -711,6 +713,7 @@ describe('MCPOAuthProvider', () => {
await MCPOAuthProvider.authenticate('test-server', mockConfig);
expect(capturedUrl).toBeDefined();
expect(capturedUrl!).toContain('response_type=code');
expect(capturedUrl!).toContain('client_id=test-client-id');
expect(capturedUrl!).toContain('code_challenge=code_challenge_mock');

View File

@@ -7,7 +7,7 @@
import * as http from 'node:http';
import * as crypto from 'node:crypto';
import { URL } from 'node:url';
import open from 'open';
import { openBrowserSecurely } from '../utils/secure-browser-launcher.js';
import { MCPOAuthToken, MCPOAuthTokenStorage } from './oauth-token-storage.js';
import { getErrorMessage } from '../utils/errors.js';
import { OAuthUtils } from './oauth-utils.js';
@@ -593,9 +593,9 @@ export class MCPOAuthProvider {
// Start callback server
const callbackPromise = this.startCallbackServer(pkceParams.state);
// Open browser
// Open browser securely
try {
await open(authUrl);
await openBrowserSecurely(authUrl);
} catch (error) {
console.warn(
'Failed to open browser automatically:',

View File

@@ -140,7 +140,7 @@ describe('OAuthUtils', () => {
describe('parseWWWAuthenticateHeader', () => {
it('should parse resource metadata URI from WWW-Authenticate header', () => {
const header =
'Bearer realm="example", resource_metadata_uri="https://example.com/.well-known/oauth-protected-resource"';
'Bearer realm="example", resource_metadata="https://example.com/.well-known/oauth-protected-resource"';
const result = OAuthUtils.parseWWWAuthenticateHeader(header);
expect(result).toBe(
'https://example.com/.well-known/oauth-protected-resource',

View File

@@ -198,8 +198,8 @@ export class OAuthUtils {
* @returns The resource metadata URI if found
*/
static parseWWWAuthenticateHeader(header: string): string | null {
// Parse Bearer realm and resource_metadata_uri
const match = header.match(/resource_metadata_uri="([^"]+)"/);
// Parse Bearer realm and resource_metadata
const match = header.match(/resource_metadata="([^"]+)"/);
if (match) {
return match[1];
}