|
| 1 | +# Cline Provider - Learnings |
| 2 | + |
| 3 | +## 2026-02-18 Task: Initial Analysis |
| 4 | +- Cline uses OAuth 2.0 via WorkOS for authentication |
| 5 | +- Base URL: `https://api.cline.bot` |
| 6 | +- Auth header format: `Bearer workos:{accessToken}` (CRITICAL: the `workos:` prefix!) |
| 7 | +- Custom headers: `HTTP-Referer: https://cline.bot`, `X-Title: Cline` |
| 8 | +- Chat completion endpoint: `POST /api/v1/chat/completions` (OpenAI-compatible) |
| 9 | +- Token response: `{ success: true, data: { accessToken, refreshToken, expiresAt, userInfo } }` |
| 10 | +- Token refresh: 5 minutes before expiry |
| 11 | +- OAuth callback: local HTTP server on ports 48801-48811 |
| 12 | +- Model IDs use OpenRouter format: `anthropic/claude-sonnet-4.6` |
| 13 | +- Free models: `["anthropic/claude-sonnet-4.6", "kwaipilot/kat-coder-pro", "z-ai/glm-5"]` |
| 14 | +- Provider constant should be `"cline"` |
| 15 | +- Kilo provider pattern is the closest reference (device flow vs OAuth, but same executor pattern) |
| 16 | +- Module path: `github.com/router-for-me/CLIProxyAPI/v6` |
| 17 | +- Use `util.NewProxyClient()` or `newProxyAwareHTTPClient()` for HTTP clients |
| 18 | +- Kilo provider executor/auth flow was a useful reference during early Cline implementation analysis. |
| 19 | + |
| 20 | +## 2026-02-18 Task: Cline auth package implementation |
| 21 | +- `internal/auth/cline/cline_token.go` was added following Kilo token persistence pattern exactly (MkdirAll 0700, JSON encode, `misc.LogSavingCredentials`, `Type="cline"`). |
| 22 | +- `ClineTokenStorage` stores `accessToken`, `refreshToken`, `expiresAt`, `email`, `userId`, `displayName`, and `type`. |
| 23 | +- `internal/auth/cline/cline_auth.go` implements WorkOS OAuth flow endpoints: |
| 24 | + - `GET /api/v1/auth/authorize` with `callbackUrl` |
| 25 | + - `POST /api/v1/auth/token` with `{code, state}` |
| 26 | + - `POST /api/v1/auth/refresh` with `{refreshToken}` |
| 27 | + - `GET /api/v1/users/me` with `Authorization: Bearer workos:{accessToken}` |
| 28 | +- Added local callback server method with automatic fallback over ports `48801..48811` and graceful shutdown after receiving code/state. |
| 29 | +- `expiresAt` parsing supports integer, float, numeric string, and RFC3339/RFC3339Nano timestamp string formats to match possible API variants. |
| 30 | + |
| 31 | +## 2026-02-18 Task: Create cline_models.go |
| 32 | +- Created `/home/jc01rho/git/cli-proxy/CLIProxyAPIPlus/internal/registry/cline_models.go` |
| 33 | +- Followed exact pattern from `kilo_models.go` (same package structure, no imports needed) |
| 34 | +- Function: `GetClineModels() []*ModelInfo` |
| 35 | +- Models defined: |
| 36 | + - `cline/auto`: Auto model selection with thinking support (200K context, 64K completion) |
| 37 | + - `anthropic/claude-sonnet-4.6`: Claude Sonnet 4.6 via Cline (200K context, 64K completion, thinking support) |
| 38 | + - `kwaipilot/kat-coder-pro`: KAT Coder Pro via Cline (128K context, 32K completion) |
| 39 | + - `z-ai/glm-5`: GLM-5 via Cline (128K context, 32K completion) |
| 40 | +- All models have Type="cline", OwnedBy="cline" |
| 41 | +- No LSP errors in the created file |
| 42 | + |
| 43 | +## 2026-02-18 Task: Create cline_executor.go |
| 44 | +- Created `/home/jc01rho/git/cli-proxy/CLIProxyAPIPlus/internal/runtime/executor/cline_executor.go` |
| 45 | +- Followed exact pattern from kilo_executor.go (same structure and method organization) |
| 46 | +- Key implementations: |
| 47 | + - `ClineExecutor` struct with config |
| 48 | + - `NewClineExecutor()` constructor |
| 49 | + - `Identifier()` returns "cline" |
| 50 | + - `PrepareRequest()` - applies Cline headers with workos: prefix |
| 51 | + - `HttpRequest()` - raw HTTP request execution |
| 52 | + - `Execute()` - non-streaming chat completion |
| 53 | + - `ExecuteStream()` - streaming chat completion with SSE handling |
| 54 | + - `Refresh()` - placeholder (returns auth as-is, will be enhanced when cline auth package is ready) |
| 55 | + - `CountTokens()` - returns unsupported error (matching Kilo pattern) |
| 56 | + - `clineCredentials()` - extracts tokens from auth metadata/attributes |
| 57 | + - `applyClineHeaders()` - sets required headers including Authorization: Bearer workos:{token} |
| 58 | + - `FetchClineModels()` - dynamic model fetching from Cline API |
| 59 | +- Critical implementation details: |
| 60 | + - Authorization header uses `Bearer workos:` prefix (CRITICAL for Cline API) |
| 61 | + - Custom headers: HTTP-Referer: https://cline.bot, X-Title: Cline |
| 62 | + - API endpoint: https://api.cline.bot/api/v1/chat/completions |
| 63 | + - Uses existing executor package utilities (newProxyAwareHTTPClient, newUsageReporter, parseOpenAIUsage, etc.) |
| 64 | +- File compiles successfully with existing codebase (verified with go build) |
| 65 | +- All comments follow Go docstring conventions matching kilo_executor.go pattern |
| 66 | + |
| 67 | +## 2026-02-18 Task: Integrate Cline into registration wiring (6-file surgical update) |
| 68 | +- Registration touched exactly 6 existing files, following Kilo registration pattern with minimal deltas. |
| 69 | +- `internal/constant/constant.go`: added `Cline = "cline"` constant for provider identity consistency. |
| 70 | +- `internal/cmd/auth_manager.go`: registered `sdkAuth.NewClineAuthenticator()` in manager constructor list. |
| 71 | +- `sdk/auth/refresh_registry.go`: added refresh lead registration for `cline` using `NewClineAuthenticator()`. |
| 72 | +- `internal/registry/model_definitions.go`: wired `case "cline"` in static channel lookup and included `GetClineModels()` in global static lookup slice. |
| 73 | +- `sdk/cliproxy/service.go`: wired executor registration (`NewClineExecutor`) and dynamic model fetch path (`FetchClineModels`). |
| 74 | +- `sdk/cliproxy/auth/oauth_model_alias.go`: added `cline` to OAuth model-alias-supported providers. |
| 75 | +- Build verification passed with `go build ./cmd/server` from `CLIProxyAPIPlus`. |
| 76 | +- LSP diagnostics tool in this session reports workspace-scoping warnings (`No active builds contain ...`) rather than code issues; build success served as functional compile verification. |
| 77 | + |
| 78 | +## 2026-02-18 Task: Cline OAuth 파라미터/토큰 교환 정합성 수정 |
| 79 | +- `/api/v1/auth/authorize` 호출 시 Cline은 `callbackUrl`이 아니라 `client_type=extension`, `callback_url`, `redirect_uri`를 기대한다. |
| 80 | +- authorize 응답은 환경에 따라 두 형태가 가능하다: (1) HTTP 3xx + `Location` 헤더, (2) 200 JSON + `redirect_url`/`url`. |
| 81 | +- OAuth state는 JSON의 `state`가 있으면 우선 사용하고, 없으면 redirect URL query의 `state`를 파싱하며, 둘 다 없을 때만 fallback 생성이 안전하다. |
| 82 | +- `/api/v1/auth/token` 교환은 `{grant_type, code, client_type, redirect_uri}` 조합이 필요하며 기존 `state` 기반 payload는 400 원인이 된다. |
| 83 | +- `ExchangeCode` 시그니처가 `callbackURL` 기반으로 바뀌면 SDK/관리 핸들러 호출부도 함께 맞춰야 컴파일 및 런타임 일관성이 유지된다. |
0 commit comments