From 0f55832be22ebfaf8b8c9172db36cff4293da322 Mon Sep 17 00:00:00 2001 From: David Torres Date: Tue, 13 Jan 2026 20:57:40 +0000 Subject: [PATCH 1/5] fix(docs): correct Claude Code configuration instructions Replace incorrect 'claude config set api_base_url' command with proper environment variable configuration in settings.json files. - Add Option A: project-specific config (.claude/settings.local.json) - Add Option B: global config (~/.claude/settings.json) - Include all required env vars (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, etc.) - Simplify steps from 6 to 4 --- README.md | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7ca9369..d383ebd 100644 --- a/README.md +++ b/README.md @@ -64,16 +64,37 @@ A proxy server that enables **Claude Code** and **Cursor IDE** to use GitHub Cop 2. Complete GitHub authentication by pasting your auth code in the browser -3. Enter `claude` in your terminal to start Claude Code - -4. Configure Claude Code to use the proxy: - ```bash - claude config set api_base_url http://localhost:3000 +3. Configure Claude Code to use the proxy by adding environment variables to your settings file: + + **Option A: Project-specific configuration** (recommended) + + Add to `.claude/settings.local.json` in your project: + ```json + { + "env": { + "ANTHROPIC_BASE_URL": "http://localhost:3000", + "ANTHROPIC_AUTH_TOKEN": "sk-dummy", + "DISABLE_NON_ESSENTIAL_MODEL_CALLS": "1", + "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" + } + } ``` -5. Press `Ctrl+C` twice to quit Claude + **Option B: Global configuration** + + Add to `~/.claude/settings.json`: + ```json + { + "env": { + "ANTHROPIC_BASE_URL": "http://localhost:3000", + "ANTHROPIC_AUTH_TOKEN": "sk-dummy", + "DISABLE_NON_ESSENTIAL_MODEL_CALLS": "1", + "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" + } + } + ``` -6. Enter `claude` again to restart with the new configuration +4. Enter `claude` in your terminal to start Claude Code with the proxy ### How to Verify It's Working From c53e99469032124fdd5b5c68e22517710f77a91b Mon Sep 17 00:00:00 2001 From: David Torres Date: Tue, 13 Jan 2026 20:59:28 +0000 Subject: [PATCH 2/5] feat: add CLI for easy npm global install - Add bin/claudecode-copilot-proxy.js CLI entry point - Add 'bin' and 'files' fields to package.json - Rename package to 'claudecode-copilot-proxy' for npm - Update README with quick install option - Support --help and --version flags Now users can install globally without cloning: npm install -g claudecode-copilot-proxy claudecode-copilot-proxy --- README.md | 20 +++++++---- bin/claudecode-copilot-proxy.js | 59 +++++++++++++++++++++++++++++++++ package-lock.json | 10 ++++++ package.json | 11 ++++-- 4 files changed, 91 insertions(+), 9 deletions(-) create mode 100755 bin/claudecode-copilot-proxy.js diff --git a/README.md b/README.md index d383ebd..22bd334 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,17 @@ A proxy server that enables **Claude Code** and **Cursor IDE** to use GitHub Cop ## 🔧 Installation +### Option A: Quick Install (Recommended) + +```bash +npm install -g claudecode-copilot-proxy +claudecode-copilot-proxy +``` + +That's it! The server will start at http://localhost:3000 + +### Option B: From Source + 1. Clone the repository: ```bash git clone https://github.com/shyamsridhar123/ClaudeCode-Copilot-Proxy.git @@ -39,17 +50,12 @@ A proxy server that enables **Claude Code** and **Cursor IDE** to use GitHub Cop npm install ``` -3. Create a `.env` file: - ```bash - cp .env.example .env - ``` - -4. Build the project: +3. Build the project: ```bash npm run build ``` -5. Start the proxy server: +4. Start the proxy server: ```bash npm start ``` diff --git a/bin/claudecode-copilot-proxy.js b/bin/claudecode-copilot-proxy.js new file mode 100755 index 0000000..6f58329 --- /dev/null +++ b/bin/claudecode-copilot-proxy.js @@ -0,0 +1,59 @@ +#!/usr/bin/env node + +/** + * CLI entry point for claudecode-copilot-proxy + * Usage: claudecode-copilot-proxy [start|--help|--version] + */ + +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; +import { readFileSync } from 'fs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const args = process.argv.slice(2); +const command = args[0] || 'start'; + +// Read package.json for version +const packageJsonPath = join(__dirname, '..', 'package.json'); +const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); + +if (command === '--version' || command === '-v') { + console.log(`claudecode-copilot-proxy v${packageJson.version}`); + process.exit(0); +} + +if (command === '--help' || command === '-h') { + console.log(` +claudecode-copilot-proxy v${packageJson.version} + +A proxy server that enables Claude Code and Cursor IDE to use GitHub Copilot's AI models. + +Usage: + claudecode-copilot-proxy [command] + +Commands: + start Start the proxy server (default) + --version Show version number + --help Show this help message + +Configuration: + PORT Server port (default: 3000) + +Example: + claudecode-copilot-proxy start + PORT=8080 claudecode-copilot-proxy + +After starting, visit http://localhost:3000 to authenticate with GitHub. + +Documentation: ${packageJson.homepage} +`); + process.exit(0); +} + +if (command === 'start' || !command.startsWith('-')) { + // Import and start the server + const serverPath = join(__dirname, '..', 'dist', 'index.js'); + await import(serverPath); +} diff --git a/package-lock.json b/package-lock.json index f6977f0..8e2bf3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,6 +74,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1912,6 +1913,7 @@ "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -2080,6 +2082,7 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -2262,6 +2265,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2670,6 +2674,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3130,6 +3135,7 @@ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -3600,6 +3606,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5048,6 +5055,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -7833,6 +7841,7 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -7926,6 +7935,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index c45d162..257e001 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,15 @@ { - "name": "github-copilot-proxy", + "name": "claudecode-copilot-proxy", "version": "0.1.0", - "description": "Proxy server that lets Cursor IDE use GitHub Copilot APIs", + "description": "Proxy server that lets Claude Code and Cursor IDE use GitHub Copilot APIs", "main": "dist/index.js", + "bin": { + "claudecode-copilot-proxy": "./bin/claudecode-copilot-proxy.js" + }, + "files": [ + "dist", + "bin" + ], "scripts": { "build": "tsc && npm run copy-assets", "copy-assets": "node -e \"require('fs').cpSync('src/public', 'dist/public', {recursive: true})\"", From 99a9de86dc817491357d6ceaf2ac85b5862fd3bd Mon Sep 17 00:00:00 2001 From: David Torres Date: Tue, 13 Jan 2026 21:26:14 +0000 Subject: [PATCH 3/5] feat: add multi-model support and simplify model mappings - Add support for GPT 5.2 and Gemini 3 Pro Preview models - Simplify Claude model mappings to use prefix matching (no date suffix needed) - Pass non-Claude models directly to Copilot API - Update README with optional model configuration - Add debug logging for model mapping Models now supported: - Claude: opus-4.5, sonnet-4.5, haiku-4.5 (default) - Optional: gpt-5.2, gemini-3-pro-preview --- README.md | 34 +++++++++++++--- package.json | 2 +- src/config/index.ts | 37 +++++++++-------- src/services/anthropic-service.ts | 66 ++++++++++++++++--------------- src/utils/model-mapper.ts | 35 ++++++++-------- 5 files changed, 103 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 22bd334..8323c6d 100644 --- a/README.md +++ b/README.md @@ -114,13 +114,35 @@ That's it! The server will start at http://localhost:3000 ✅ **Usage stats**: Check http://localhost:3000/usage.html in your browser to see how many tokens you've used -### Supported Claude Models +### Supported Models + +| Model | Description | +|-------|-------------| +| `claude-opus-4.5` | Claude Opus 4.5 (Default) | +| `claude-sonnet-4.5` | Claude Sonnet 4.5 | +| `claude-haiku-4.5` | Claude Haiku 4.5 | + +### Optional: Use Other Models + +The proxy also supports GPT and Gemini models available in GitHub Copilot. To use them, add `ANTHROPIC_MODEL` to your settings: + +```json +{ + "env": { + "ANTHROPIC_BASE_URL": "http://localhost:3000", + "ANTHROPIC_AUTH_TOKEN": "sk-dummy", + "ANTHROPIC_MODEL": "gpt-5.2", + "ANTHROPIC_DEFAULT_HAIKU_MODEL": "gemini-3-pro-preview", + "DISABLE_NON_ESSENTIAL_MODEL_CALLS": "1", + "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" + } +} +``` -| Model | Copilot Model | -|-------|---------------| -| `claude-opus-4-5-20250514` | Claude Opus 4.5 | -| `claude-sonnet-4-5-20250514` | Claude Sonnet 4.5 | -| `claude-haiku-4-5-20250514` | Claude Haiku 4.5 | +| Model | Description | +|-------|-------------| +| `gpt-5.2` | GPT 5.2 | +| `gemini-3-pro-preview` | Gemini 3 Pro Preview | ## 🔌 Configuration with Cursor IDE diff --git a/package.json b/package.json index 257e001..f0a3a74 100644 --- a/package.json +++ b/package.json @@ -73,4 +73,4 @@ "engines": { "node": ">=18.0.0" } -} +} \ No newline at end of file diff --git a/src/config/index.ts b/src/config/index.ts index ed83b85..697ea7d 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -41,44 +41,49 @@ const ANTHROPIC_API_ENDPOINTS = { }; // Claude model mappings: Claude Code model names -> Copilot model names +// Uses prefix matching, so 'claude-opus-4-5' matches 'claude-opus-4-5-20251001' etc. export const CLAUDE_MODEL_MAPPINGS: Record = { - // Claude Opus 4.5 (default - latest flagship) - 'claude-opus-4-5-20250514': 'claude-opus-4.5', - 'claude-opus-4.5': 'claude-opus-4.5', + // Claude Opus 4.5 + 'claude-opus-4-5': 'claude-opus-4.5', 'opus': 'claude-opus-4.5', - + // Claude Sonnet 4.5 - 'claude-sonnet-4-5-20250514': 'claude-sonnet-4.5', - 'claude-sonnet-4.5': 'claude-sonnet-4.5', - 'claude-sonnet-4-20250514': 'claude-sonnet-4.5', - 'claude-sonnet-4': 'claude-sonnet-4.5', + 'claude-sonnet-4-5': 'claude-sonnet-4.5', 'sonnet': 'claude-sonnet-4.5', - + // Claude Haiku 4.5 - 'claude-haiku-4-5-20250514': 'claude-haiku-4.5', - 'claude-haiku-4.5': 'claude-haiku-4.5', - 'claude-3-5-haiku-20241022': 'claude-haiku-4.5', - 'claude-3.5-haiku': 'claude-haiku-4.5', + 'claude-haiku-4-5': 'claude-haiku-4.5', 'haiku': 'claude-haiku-4.5', }; // Available Claude models via Copilot (Opus 4.5 is default) export const AVAILABLE_CLAUDE_MODELS = [ { - id: 'claude-opus-4-5-20250514', + id: 'claude-opus-4-5', display_name: 'Claude Opus 4.5 (Default)', copilot_model: 'claude-opus-4.5', }, { - id: 'claude-sonnet-4-5-20250514', + id: 'claude-sonnet-4-5', display_name: 'Claude Sonnet 4.5', copilot_model: 'claude-sonnet-4.5', }, { - id: 'claude-haiku-4-5-20250514', + id: 'claude-haiku-4-5', display_name: 'Claude Haiku 4.5', copilot_model: 'claude-haiku-4.5', }, + // Optional: GPT and Gemini models (pass-through, user must specify in settings) + { + id: 'gpt-5.2', + display_name: 'GPT 5.2 (Optional)', + copilot_model: 'gpt-5.2', + }, + { + id: 'gemini-3-pro-preview', + display_name: 'Gemini 3 Pro Preview (Optional)', + copilot_model: 'gemini-3-pro-preview', + }, ]; // Configuration object diff --git a/src/services/anthropic-service.ts b/src/services/anthropic-service.ts index 22fea15..4ba6384 100644 --- a/src/services/anthropic-service.ts +++ b/src/services/anthropic-service.ts @@ -7,9 +7,9 @@ import fetch from 'node-fetch'; import { v4 as uuidv4 } from 'uuid'; import { config } from '../config/index.js'; -import { - AnthropicMessage, - AnthropicMessageRequest, +import { + AnthropicMessage, + AnthropicMessageRequest, AnthropicMessageResponse, ContentBlock, TextBlock, @@ -35,30 +35,30 @@ export function convertAnthropicMessagesToCopilotPrompt( if (!messages || !Array.isArray(messages) || messages.length === 0) { return systemPrompt ? systemPrompt + '\n\n' : ''; } - + let prompt = ''; - + // Add system prompt at the beginning if provided if (systemPrompt) { prompt += systemPrompt + '\n\n'; } - + // Process each message for (const message of messages) { const role = message.role === 'user' ? 'Human' : 'Assistant'; const content = extractTextContent(message.content); - + if (content) { prompt += `${role}: ${content}\n\n`; } } - + // If the last message was from the user, prompt for assistant response const lastMessage = messages[messages.length - 1]; if (lastMessage && lastMessage.role === 'user') { prompt += 'Assistant: '; } - + return prompt; } @@ -72,11 +72,11 @@ export function extractTextContent(content: string | ContentBlock[]): string { if (typeof content === 'string') { return content; } - + if (!Array.isArray(content)) { return ''; } - + // Extract text from all text blocks return content .filter((block): block is TextBlock => block.type === 'text') @@ -99,7 +99,7 @@ export function convertCopilotToAnthropicResponse( const text = copilotResponse.choices .map((choice) => choice.text) .join(''); - + // Build content blocks const content: ContentBlock[] = []; if (text) { @@ -108,13 +108,13 @@ export function convertCopilotToAnthropicResponse( text: text.trim(), }); } - + // Calculate usage const usage: AnthropicUsage = { input_tokens: copilotResponse.usage?.prompt_tokens || 0, output_tokens: copilotResponse.usage?.completion_tokens || 0, }; - + // Determine stop reason let stopReason: AnthropicMessageResponse['stop_reason'] = 'end_turn'; const finishReason = copilotResponse.choices[0]?.finish_reason; @@ -123,7 +123,7 @@ export function convertCopilotToAnthropicResponse( } else if (finishReason === 'stop') { stopReason = 'stop_sequence'; } - + return { id: `msg_${copilotResponse.id || uuidv4()}`, type: 'message', @@ -148,16 +148,18 @@ export async function makeAnthropicCompletionRequest( copilotToken: string ): Promise { const { messages, system, temperature, max_tokens, model } = request; - + // Map the model name to Copilot's model name const copilotModel = mapClaudeModelToCopilot(model); - + + logger.info(`Model mapping: "${model}" -> "${copilotModel}"`); + // Get machine ID const machineId = getMachineId(); - + // Use Copilot's chat completions endpoint (OpenAI-compatible) const chatEndpoint = config.github.copilot.anthropicEndpoints.COPILOT_ANTHROPIC_CHAT; - + const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${copilotToken}`, @@ -169,18 +171,18 @@ export async function makeAnthropicCompletionRequest( 'Openai-Organization': 'github-copilot', 'Openai-Intent': 'conversation-agent', }; - + // Build OpenAI-compatible request body // Prepend system message if provided const openaiMessages: Array<{ role: string; content: string }> = []; - + if (system) { openaiMessages.push({ role: 'system', content: system, }); } - + // Convert Anthropic messages to OpenAI format for (const msg of messages) { openaiMessages.push({ @@ -188,7 +190,7 @@ export async function makeAnthropicCompletionRequest( content: typeof msg.content === 'string' ? msg.content : extractTextContent(msg.content), }); } - + const body = { model: copilotModel, messages: openaiMessages, @@ -196,31 +198,31 @@ export async function makeAnthropicCompletionRequest( temperature: temperature ?? 0.7, stream: false, }; - + try { - logger.debug('Making chat completion request to Copilot', { + logger.debug('Making chat completion request to Copilot', { endpoint: chatEndpoint, model: copilotModel, }); - + const response = await fetch(chatEndpoint, { method: 'POST', headers, body: JSON.stringify(body), }); - + if (!response.ok) { const errorText = await response.text(); - logger.error('Copilot chat API error', { - status: response.status, + logger.error('Copilot chat API error', { + status: response.status, statusText: response.statusText, body: errorText, }); throw new Error(`Copilot API error: ${response.status} ${response.statusText}`); } - + const data = await response.json() as Record; - + // Convert OpenAI chat response to Anthropic format return convertOpenAIToAnthropicResponse(data, model); } catch (error) { @@ -241,7 +243,7 @@ function convertOpenAIToAnthropicResponse( const message = firstChoice.message || {}; const content = (message.content as string) || ''; const usage = (data.usage as { prompt_tokens?: number; completion_tokens?: number }) || {}; - + return { id: `msg_${uuidv4().replace(/-/g, '').substring(0, 24)}`, type: 'message', diff --git a/src/utils/model-mapper.ts b/src/utils/model-mapper.ts index 48973e3..4f34a94 100644 --- a/src/utils/model-mapper.ts +++ b/src/utils/model-mapper.ts @@ -1,32 +1,35 @@ /** * Model mapping utilities for Claude Code -> GitHub Copilot + * + * Supports Claude, GPT, Gemini, and other models available in Copilot */ import { CLAUDE_MODEL_MAPPINGS, AVAILABLE_CLAUDE_MODELS } from '../config/index.js'; import { AnthropicModel, AnthropicModelList } from '../types/anthropic.js'; /** - * Map a Claude Code model name to the Copilot model name + * Map a model name to the Copilot model name * - * @param claudeModel - The model name from Claude Code (e.g., "claude-opus-4-5-20250514") - * @returns The corresponding Copilot model name (e.g., "claude-opus-4.5") + * @param model - The model name (e.g., "claude-opus-4-5-20250514", "gpt-5.2", "gemini-3-pro") + * @returns The corresponding Copilot model name */ -export function mapClaudeModelToCopilot(claudeModel: string): string { - // Check if we have a direct mapping - const mapped = CLAUDE_MODEL_MAPPINGS[claudeModel]; +export function mapClaudeModelToCopilot(model: string): string { + // Check if we have a direct mapping for Claude models + const mapped = CLAUDE_MODEL_MAPPINGS[model]; if (mapped) { return mapped; } - + // Check for partial matches (model name might have extra suffix) for (const [key, value] of Object.entries(CLAUDE_MODEL_MAPPINGS)) { - if (claudeModel.startsWith(key) || key.startsWith(claudeModel)) { + if (model.startsWith(key) || key.startsWith(model)) { return value; } } - - // Default fallback: use claude-opus-4.5 as default (user requested) - return 'claude-opus-4.5'; + + // For non-Claude models (GPT, Gemini, etc.), pass through as-is + // GitHub Copilot supports multiple model providers + return model; } /** @@ -40,13 +43,13 @@ export function isValidClaudeModel(model: string): boolean { if (CLAUDE_MODEL_MAPPINGS[model]) { return true; } - + // Check if it's a Copilot model name const copilotModels = Object.values(CLAUDE_MODEL_MAPPINGS); if (copilotModels.includes(model)) { return true; } - + // Check if it starts with 'claude' return model.toLowerCase().startsWith('claude'); } @@ -64,7 +67,7 @@ export function getAvailableModels(): AnthropicModelList { owned_by: 'anthropic', display_name: model.display_name, })); - + return { object: 'list', data: models, @@ -81,11 +84,11 @@ export function getModelDisplayName(model: string): string { const found = AVAILABLE_CLAUDE_MODELS.find( (m) => m.id === model || m.copilot_model === model ); - + if (found) { return found.display_name; } - + // Generate a display name from the model ID return model .replace(/-/g, ' ') From dd8d04ebae61cc418ecc1964534318db41d24e55 Mon Sep 17 00:00:00 2001 From: David Torres Date: Tue, 13 Jan 2026 21:46:14 +0000 Subject: [PATCH 4/5] feat: update auth page to mention Claude Code support - Changed success message to include Claude Code alongside Cursor IDE - Added Claude Code Setup section with settings.local.json configuration example - Shows users how to configure environment variables for Claude Code --- src/public/auth.html | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/public/auth.html b/src/public/auth.html index fab29b3..2b66b0c 100644 --- a/src/public/auth.html +++ b/src/public/auth.html @@ -123,7 +123,7 @@

Enter this code on GitHub

@@ -133,9 +133,17 @@

Authentication Successful!

Setup Instructions

  1. Complete the authentication process above
  2. -
  3. In Cursor IDE, go to Settings > API Keys
  4. +
  5. For Cursor IDE: Go to Settings > API Keys
  6. In the "Override OpenAI Base URL" section, enter: http://localhost:3000
  7. -
  8. Start using Cursor IDE with GitHub Copilot!
  9. +
  10. For Claude Code: Add to .claude/settings.local.json: +
    {
    +  "env": {
    +    "ANTHROPIC_BASE_URL": "http://localhost:3000",
    +    "ANTHROPIC_AUTH_TOKEN": "sk-dummy"
    +  }
    +}
    +
  11. +
  12. Start using Cursor IDE or Claude Code with GitHub Copilot!
From 0454344133cc6e5e3e171098145d68bda7c51b9c Mon Sep 17 00:00:00 2001 From: David Torres Date: Tue, 13 Jan 2026 21:48:44 +0000 Subject: [PATCH 5/5] style: format auth.html --- src/public/auth.html | 98 ++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/src/public/auth.html b/src/public/auth.html index 2b66b0c..eb36f64 100644 --- a/src/public/auth.html +++ b/src/public/auth.html @@ -1,12 +1,13 @@ + GitHub Copilot Proxy - Authentication + -