This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
bun install # Install dependencies
bun run dev # Dev mode with watch
bun run build # Build to dist/ via tsdown
bun run start # Production start (NODE_ENV=production)
bun run lint # ESLint with cache (auto-fixes staged files pre-commit)
bun run lint:all # ESLint on entire project
bun run typecheck # tsc type check only (no emit)
bun test # Run all tests
bun test tests/foo.test.ts # Run a single test fileThis is a reverse-engineered proxy that exposes the GitHub Copilot API as both an OpenAI-compatible and Anthropic-compatible HTTP service. The entry point is src/main.ts (CLI via citty), which dispatches to subcommands: start, auth, check-usage, debug.
src/routes/messages/handler.ts is the core dispatch logic:
- Rate limit check
- Parse Anthropic payload
- Detect subagent marker (
__SUBAGENT_MARKER__in<system-reminder>) → setsx-initiator: agent - Detect compact requests (Claude Code context compaction)
- Force
smallModelfor tool-less warmup/probe requests - Merge mixed
tool_result+ text blocks to avoid fresh premium request - Normalize model ID → look up Copilot model
- Route to one of three upstream flows:
handleWithMessagesApi— Copilot native/v1/messages(Claude models, preferred)handleWithResponsesApi— Copilot/responses(GPT models)handleWithChatCompletions— fallback for everything else
| Path | Purpose |
|---|---|
src/server.ts |
Hono app, middleware stack, route registration |
src/lib/ |
Shared utilities: config, state, auth, tokens, rate-limit, models, tokenizer, trace |
src/routes/ |
Route handlers grouped by endpoint family |
src/services/ |
Upstream API clients (Copilot, GitHub, providers) |
tests/ |
All test files (*.test.ts), Bun built-in runner |
traceIdMiddleware → logger() → cors() → createAuthMiddleware (API key validation via x-api-key or Authorization: Bearer; unauthenticated paths: /, /usage-viewer)
src/lib/models.ts normalizes Claude model IDs via 5 regex patterns (handles variants like claude-opus-4-6, claude-opus-4.6). The useMessagesApi config flag (default true) controls whether Claude-family models use the native Messages API or fall back to Chat Completions.
src/lib/config.ts—AppConfigshape, disk read/write from~/.local/share/copilot-api/config.json(Linux/macOS) or%USERPROFILE%\.local\share\copilot-api\config.json(Windows). Also respectsCOPILOT_API_HOMEenv var.src/lib/state.ts— singleton mutable state: tokens, accountType, rate-limit, models cache.
/v1/messages/count_tokens: when anthropicApiKey is configured, forwards Claude model requests to Anthropic's free /v1/messages/count_tokens endpoint for exact counts. Otherwise falls back to GPT o200k_base tokenizer with 1.15x multiplier (src/lib/tokenizer.ts).
- Imports: Use
~/alias forsrc/(e.g.,import { foo } from '~/lib/foo') - TypeScript: Strict mode — no
any,noUnusedLocals,noUnusedParameters - Modules: ESNext only, no CommonJS
- Naming:
camelCasefor functions/variables,PascalCasefor types/interfaces - Error handling: Route handlers catch and call
forwardError(c, error); useHTTPErrorfromsrc/lib/error.ts - Streaming: All three API flows support both streaming (SSE via
streamSSE) and non-streaming, switching onpayload.stream
- Claude Code agent-inject plugin: Install from marketplace with
/plugin marketplace add https://github.com/caozhiyuan/copilot-api.gitthen/plugin install agent-inject@copilot-api-marketplace. Injects__SUBAGENT_MARKER__on subagent starts. - Claude Code tool-search plugin: Install from the same marketplace with
/plugin install tool-search@copilot-api-marketplace. Registers thetool_searchMCP bridge. - Opencode plugin: Copy
plugin/opencode/subagent-marker.jsto~/.config/opencode/plugins/.