Skip to content

Commit 575f842

Browse files
committed
Add project documentation and ignore rules
Document usage, endpoints, model aliases, build commands, and local-only paths.
1 parent 38d951b commit 575f842

3 files changed

Lines changed: 262 additions & 0 deletions

File tree

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Binaries
2+
bin/
3+
4+
# Drafts
5+
.drafts/
6+
7+
# Claude config
8+
.claude/
9+
10+
# Go build cache
11+
go.sum
12+
*.exe
13+
*.exe~
14+
15+
# OS files
16+
.DS_Store
17+
Thumbs.db
18+
19+
# IDE
20+
.idea/
21+
.vscode/

README.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# CommandCode Proxy Server
2+
3+
OpenAI-compatible proxy server for the CommandCode API. It exposes `/v1/chat/completions` and `/v1/models` endpoints so OpenAI-compatible clients can call CommandCode models through a local HTTP server.
4+
5+
Repository: https://github.com/dev2k6/command-code-proxy-server
6+
7+
Version: `v1.0.0`
8+
9+
## Features
10+
11+
- OpenAI-compatible chat completions endpoint
12+
- Streaming and non-streaming responses
13+
- OpenAI-compatible model list endpoint
14+
- Short model name mapping
15+
- Optional default API key from CLI
16+
- Per-request API key via `Authorization` header
17+
- Configurable host and port
18+
- Checks GitHub tags for a newer proxy version and displays it next to the current version
19+
20+
## Requirements
21+
22+
- Go 1.26.2 or newer
23+
24+
## Run
25+
26+
```bash
27+
go run main.go
28+
```
29+
30+
Default server address:
31+
32+
```text
33+
http://127.0.0.1:55990
34+
```
35+
36+
## CLI options
37+
38+
```bash
39+
go run main.go [options]
40+
```
41+
42+
| Option | Default | Description |
43+
| --- | --- | --- |
44+
| `-host` | `127.0.0.1` | Host to bind the server to |
45+
| `-port` | `55990` | Port to run the server on |
46+
| `-api-key` | empty | Optional default CommandCode API key |
47+
| `-version` | `false` | Print version and exit |
48+
49+
Examples:
50+
51+
```bash
52+
# Run on default host and port
53+
go run main.go
54+
55+
# Run on a custom port
56+
go run main.go -port 8080
57+
58+
# Expose on all interfaces
59+
go run main.go -host 0.0.0.0
60+
61+
# Use a default API key for all requests that do not include Authorization
62+
go run main.go -api-key your-commandcode-api-key
63+
64+
# Print version
65+
go run main.go -version
66+
```
67+
68+
## Build
69+
70+
Build for the current platform:
71+
72+
```bash
73+
go build -o bin/command-code-proxy
74+
```
75+
76+
Cross-compile for Windows and Linux:
77+
78+
```bash
79+
GOOS=windows GOARCH=amd64 go build -o bin/command-code-proxy.exe
80+
GOOS=linux GOARCH=amd64 go build -o bin/command-code-proxy
81+
```
82+
83+
## API key behavior
84+
85+
The proxy uses the API key in this order:
86+
87+
1. `Authorization` header from the incoming client request
88+
2. `-api-key` CLI value
89+
3. If neither exists, the request returns `401 Unauthorized`
90+
91+
Header format:
92+
93+
```http
94+
Authorization: Bearer your-commandcode-api-key
95+
```
96+
97+
## Endpoints
98+
99+
### Health check
100+
101+
```http
102+
GET /health
103+
```
104+
105+
Response:
106+
107+
```json
108+
{"status":"ok"}
109+
```
110+
111+
### List models
112+
113+
```http
114+
GET /v1/models
115+
```
116+
117+
Returns an OpenAI-compatible model list.
118+
119+
### Chat completions
120+
121+
```http
122+
POST /v1/chat/completions
123+
```
124+
125+
Example non-streaming request:
126+
127+
```bash
128+
curl http://127.0.0.1:55990/v1/chat/completions \
129+
-H "Content-Type: application/json" \
130+
-H "Authorization: Bearer your-commandcode-api-key" \
131+
-d '{
132+
"model": "deepseek-v4-pro",
133+
"messages": [
134+
{"role": "system", "content": "You are helpful."},
135+
{"role": "user", "content": "Hello"}
136+
],
137+
"stream": false
138+
}'
139+
```
140+
141+
Example streaming request:
142+
143+
```bash
144+
curl -N http://127.0.0.1:55990/v1/chat/completions \
145+
-H "Content-Type: application/json" \
146+
-H "Authorization: Bearer your-commandcode-api-key" \
147+
-d '{
148+
"model": "deepseek-v4-pro",
149+
"messages": [
150+
{"role": "user", "content": "Write a short poem."}
151+
],
152+
"stream": true
153+
}'
154+
```
155+
156+
## Supported model aliases
157+
158+
The proxy accepts full model IDs and these short aliases:
159+
160+
| Alias | Maps to |
161+
| --- | --- |
162+
| `deepseek-v4-pro`, `deepseek-v4`, `deepseek-pro` | `deepseek/deepseek-v4-pro` |
163+
| `deepseek-v4-flash`, `deepseek-flash` | `deepseek/deepseek-v4-flash` |
164+
| `minimax-m2.7`, `minimax2.7` | `MiniMaxAI/MiniMax-M2.7` |
165+
| `minimax-m2.5`, `minimax2.5`, `minimax` | `MiniMaxAI/MiniMax-M2.5` |
166+
| `glm-5.1` | `zai-org/GLM-5.1` |
167+
| `glm-5` | `zai-org/GLM-5` |
168+
| `kimi-k2.6`, `kimi2.6` | `moonshotai/Kimi-K2.6` |
169+
| `kimi-k2.5`, `kimi2.5` | `moonshotai/Kimi-K2.5` |
170+
| `qwen-3.6-max-preview`, `qwen3.6-max` | `Qwen/Qwen3.6-Max-Preview` |
171+
| `qwen-3.6-plus`, `qwen3.6-plus`, `qwen3.6` | `Qwen/Qwen3.6-Plus` |
172+
| `step-3.5-flash`, `step3.5` | `stepfun/Step-3.5-Flash` |
173+
| `gemini-3.1-flash-lite`, `gemini-flash-lite` | `google/gemini-3.1-flash-lite` |
174+
175+
Unknown model names are passed through unchanged.
176+
177+
## Project structure
178+
179+
```text
180+
.
181+
├── README.md
182+
├── go.mod
183+
├── go.sum
184+
├── main.go
185+
├── bin
186+
│ ├── command-code-proxy
187+
│ └── command-code-proxy.exe
188+
└── internal
189+
├── api
190+
│ ├── commandcode.go
191+
│ └── openai.go
192+
├── proxy
193+
│ ├── convert.go
194+
│ ├── model.go
195+
│ └── proxy.go
196+
├── server
197+
│ └── server.go
198+
├── update
199+
│ └── update.go
200+
└── version
201+
└── version.go
202+
```
203+
204+
## How it works
205+
206+
1. Client sends an OpenAI-compatible request to the local proxy.
207+
2. The proxy extracts system messages, maps the model name, and converts messages to CommandCode format.
208+
3. The proxy sends the request to `https://api.commandcode.ai/alpha/generate`.
209+
4. CommandCode streaming NDJSON events are converted back to OpenAI-compatible SSE chunks or collected into a single JSON response.
210+
211+
## Version check
212+
213+
On startup and when running `-version`, the proxy calls:
214+
215+
```text
216+
https://api.github.com/repos/dev2k6/command-code-proxy-server/tags
217+
```
218+
219+
If the latest GitHub tag is newer than the current app version, the version line is displayed as:
220+
221+
```text
222+
v1.0.0 (latest: v1.x.x)
223+
```
224+
225+
## CommandCode version header
226+
227+
The upstream request includes:
228+
229+
```http
230+
x-command-code-version: <latest npm command-code version>
231+
```
232+
233+
The value is fetched from:
234+
235+
```text
236+
https://registry.npmjs.org/command-code/latest
237+
```
238+
239+
The fetched version is cached for 30 minutes. If the registry request fails, the proxy uses the last cached version, or `unknown` if no version has been fetched yet.

0 commit comments

Comments
 (0)