commandcode-api-proxy 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -0
  3. package/dist/auth.d.ts +7 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +77 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/config.d.ts +22 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +67 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/logger.d.ts +9 -0
  12. package/dist/logger.d.ts.map +1 -0
  13. package/dist/logger.js +36 -0
  14. package/dist/logger.js.map +1 -0
  15. package/dist/models.json +89 -0
  16. package/dist/proxy.d.ts +3 -0
  17. package/dist/proxy.d.ts.map +1 -0
  18. package/dist/proxy.js +80 -0
  19. package/dist/proxy.js.map +1 -0
  20. package/dist/server.d.ts +4 -0
  21. package/dist/server.d.ts.map +1 -0
  22. package/dist/server.js +259 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/setup/opencode.d.ts +2 -0
  25. package/dist/setup/opencode.d.ts.map +1 -0
  26. package/dist/setup/opencode.js +58 -0
  27. package/dist/setup/opencode.js.map +1 -0
  28. package/dist/stream.d.ts +38 -0
  29. package/dist/stream.d.ts.map +1 -0
  30. package/dist/stream.js +89 -0
  31. package/dist/stream.js.map +1 -0
  32. package/dist/translate/models.d.ts +9 -0
  33. package/dist/translate/models.d.ts.map +1 -0
  34. package/dist/translate/models.js +41 -0
  35. package/dist/translate/models.js.map +1 -0
  36. package/dist/translate/openai.d.ts +13 -0
  37. package/dist/translate/openai.d.ts.map +1 -0
  38. package/dist/translate/openai.js +470 -0
  39. package/dist/translate/openai.js.map +1 -0
  40. package/dist/translate/types.d.ts +110 -0
  41. package/dist/translate/types.d.ts.map +1 -0
  42. package/dist/translate/types.js +3 -0
  43. package/dist/translate/types.js.map +1 -0
  44. package/dist/translate/util.d.ts +12 -0
  45. package/dist/translate/util.d.ts.map +1 -0
  46. package/dist/translate/util.js +114 -0
  47. package/dist/translate/util.js.map +1 -0
  48. package/dist/translate/validation.d.ts +6 -0
  49. package/dist/translate/validation.d.ts.map +1 -0
  50. package/dist/translate/validation.js +34 -0
  51. package/dist/translate/validation.js.map +1 -0
  52. package/dist/upstream.d.ts +41 -0
  53. package/dist/upstream.d.ts.map +1 -0
  54. package/dist/upstream.js +167 -0
  55. package/dist/upstream.js.map +1 -0
  56. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 thaolaptrinh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # Command Code API Proxy
2
+
3
+ **OpenAI-compatible API proxy for [Command Code](https://commandcode.ai).**
4
+ Use your Command Code subscription from **any** OpenAI-compatible client — OpenCode, Continue, the OpenAI SDK, or plain `curl`.
5
+
6
+ ```
7
+ npx commandcode-api-proxy
8
+ ```
9
+
10
+ ## Why?
11
+
12
+ Command Code exposes two API surfaces:
13
+
14
+ | Surface | Protocol | Plan required |
15
+ | ------------------------------- | ----------------------------- | ------------------------------- |
16
+ | `/provider/v1/chat/completions` | OpenAI-compatible | **Provider** tier (paid add-on) |
17
+ | `/alpha/generate` | Custom (Vercel AI SDK stream) | Your standard subscription |
18
+
19
+ This proxy talks `/alpha/generate` upstream and standard OpenAI downstream — so your existing plan works from any tool.
20
+
21
+ ## Quick start
22
+
23
+ ```bash
24
+ # Run directly (no install)
25
+ npx commandcode-api-proxy
26
+
27
+ # Or install globally
28
+ npm install -g commandcode-api-proxy
29
+ commandcode-api-proxy
30
+ ```
31
+
32
+ ### Authentication
33
+
34
+ The proxy loads your API key from (in order of priority):
35
+
36
+ 1. `--api-key` CLI flag: `npx commandcode-api-proxy --api-key user_xxx`
37
+ 2. `CC_API_KEY` environment variable
38
+ 3. `~/.config/commandcode-api-proxy/auth.json` (saved via `auth login`)
39
+
40
+ On first run without a key, the proxy prompts you to enter one and persists it.
41
+
42
+ #### CLI auth commands
43
+
44
+ ```bash
45
+ # Save a new API key
46
+ commandcode-api-proxy auth login
47
+
48
+ # Overwrite existing key
49
+ commandcode-api-proxy auth login --force
50
+
51
+ # Remove saved key
52
+ commandcode-api-proxy auth logout
53
+ ```
54
+
55
+ Get your API key from https://commandcode.ai/settings.
56
+
57
+ ### CLI options
58
+
59
+ | Option | Description | Default |
60
+ | ----------- | -------------------- | ----------- |
61
+ | `--host` | Bind address | `127.0.0.1` |
62
+ | `--port` | Port | `8787` |
63
+ | `--api-key` | Command Code API key | — |
64
+ | `--setup-opencode` | Generate OpenCode provider config | — |
65
+
66
+ ## Endpoints
67
+
68
+ ### `POST /v1/chat/completions` (OpenAI)
69
+
70
+ ```bash
71
+ curl http://127.0.0.1:8787/v1/chat/completions \
72
+ -H "Authorization: Bearer proxy-managed" \
73
+ -H "Content-Type: application/json" \
74
+ -d '{
75
+ "model": "deepseek/deepseek-v4-pro",
76
+ "messages": [{"role": "user", "content": "Hello!"}],
77
+ "stream": true
78
+ }'
79
+ ```
80
+
81
+ ## Client configuration
82
+
83
+ ### OpenCode
84
+
85
+ Run setup (writes to `~/.config/opencode/opencode.json`):
86
+
87
+ ```bash
88
+ npx commandcode-api-proxy --setup-opencode
89
+ ```
90
+
91
+ Or add manually:
92
+
93
+ ```json
94
+ {
95
+ "$schema": "https://opencode.ai/config.json",
96
+ "provider": {
97
+ "commandcode": {
98
+ "npm": "@ai-sdk/openai-compatible",
99
+ "name": "Command Code",
100
+ "options": {
101
+ "baseURL": "http://127.0.0.1:8787/v1",
102
+ "apiKey": "proxy-managed"
103
+ },
104
+ "models": {
105
+ "deepseek-v4-pro": { "name": "DeepSeek V4 Pro", "limit": { "context": 1048576, "output": 393216 } },
106
+ "deepseek-v4-flash": { "name": "DeepSeek V4 Flash", "limit": { "context": 1048576, "output": 393216 } },
107
+ "MiniMax-M2.7": { "name": "MiniMax M2.7", "limit": { "context": 204800, "output": 32768 } },
108
+ "MiniMax-M2.5": { "name": "MiniMax M2.5", "limit": { "context": 204800, "output": 32768 } },
109
+ "GLM-5.1": { "name": "GLM-5.1", "limit": { "context": 200000, "output": 131072 } },
110
+ "GLM-5": { "name": "GLM-5", "limit": { "context": 200000, "output": 131072 } },
111
+ "Kimi-K2.6": { "name": "Kimi K2.6", "limit": { "context": 262144, "output": 98304 } },
112
+ "Kimi-K2.5": { "name": "Kimi K2.5", "limit": { "context": 262144, "output": 98304 } },
113
+ "Qwen3.6-Max-Preview": { "name": "Qwen 3.6 Max Preview", "limit": { "context": 262144, "output": 65536 } },
114
+ "Qwen3.6-Plus": { "name": "Qwen 3.6 Plus", "limit": { "context": 1048576, "output": 65536 } },
115
+ "Qwen3.7-Max": { "name": "Qwen 3.7 Max", "limit": { "context": 1048576, "output": 65536 } },
116
+ "Qwen3.7-Plus": { "name": "Qwen 3.7 Plus", "limit": { "context": 1048576, "output": 65536 } },
117
+ "Step-3.5-Flash": { "name": "Step 3.5 Flash", "limit": { "context": 262144, "output": 65536 } },
118
+ "mimo-v2.5": { "name": "MiMo V2.5", "limit": { "context": 1048576, "output": 131072 } }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ ### OpenAI Python SDK
126
+
127
+ ```python
128
+ from openai import OpenAI
129
+
130
+ client = OpenAI(
131
+ base_url="http://127.0.0.1:8787/v1",
132
+ api_key="proxy-managed",
133
+ )
134
+
135
+ response = client.chat.completions.create(
136
+ model="deepseek/deepseek-v4-pro",
137
+ messages=[{"role": "user", "content": "Hello!"}],
138
+ )
139
+ ```
140
+
141
+ ### Continue
142
+
143
+ ```json
144
+ {
145
+ "models": [
146
+ {
147
+ "title": "Command Code",
148
+ "provider": "openai",
149
+ "model": "deepseek/deepseek-v4-pro",
150
+ "apiKey": "proxy-managed",
151
+ "apiBase": "http://127.0.0.1:8787/v1"
152
+ }
153
+ ]
154
+ }
155
+ ```
156
+
157
+ ## Model aliases
158
+
159
+ Short names work in addition to full model IDs:
160
+
161
+ | Alias | Maps to |
162
+ | -------------------------------------- | ---------------------------- |
163
+ | `deepseek-v4-pro`, `deepseek-v4` | `deepseek/deepseek-v4-pro` |
164
+ | `deepseek-v4-flash`, `deepseek-flash` | `deepseek/deepseek-v4-flash` |
165
+ | `minimax-m2.7`, `minimax-m2.5` | `MiniMaxAI/MiniMax-*` |
166
+ | `glm-5.1`, `glm-5` | `zai-org/GLM-*` |
167
+ | `kimi-k2.6`, `kimi-k2.5` | `moonshotai/Kimi-*` |
168
+ | `qwen3.6-max`, `qwen3.6-plus` | `Qwen/Qwen3.6-*` |
169
+ | `step3.5` | `stepfun/Step-3.5-Flash` |
170
+ | `mimo-v2.5` | `xiaomi/mimo-v2.5` |
171
+
172
+ Any model ID is passed through as-is — the proxy does not validate against a fixed list.
173
+
174
+ ## License
175
+
176
+ MIT
package/dist/auth.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export declare function getAuthDir(): string;
2
+ export declare function getAuthPath(): string;
3
+ export declare function readAuthKey(): string | null;
4
+ export declare function saveApiKey(key: string): void;
5
+ export declare function deleteAuth(): void;
6
+ export declare function promptForApiKey(): Promise<string>;
7
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAKA,wBAAgB,UAAU,IAAI,MAAM,CAInC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAQ3C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAI5C;AAED,wBAAgB,UAAU,IAAI,IAAI,CAMjC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAuCvD"}
package/dist/auth.js ADDED
@@ -0,0 +1,77 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import readline from "node:readline";
4
+ export function getAuthDir() {
5
+ const home = process.env.HOME || process.env.USERPROFILE;
6
+ if (!home)
7
+ throw new Error("Cannot determine home directory");
8
+ return path.join(home, ".config", "commandcode-api-proxy");
9
+ }
10
+ export function getAuthPath() {
11
+ return path.join(getAuthDir(), "auth.json");
12
+ }
13
+ export function readAuthKey() {
14
+ try {
15
+ const raw = fs.readFileSync(getAuthPath(), "utf-8");
16
+ const parsed = JSON.parse(raw);
17
+ return parsed.apiKey || parsed.accessToken || parsed.token || null;
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ export function saveApiKey(key) {
24
+ const dir = getAuthDir();
25
+ fs.mkdirSync(dir, { recursive: true });
26
+ fs.writeFileSync(getAuthPath(), JSON.stringify({ apiKey: key }, null, 2) + "\n");
27
+ }
28
+ export function deleteAuth() {
29
+ try {
30
+ fs.unlinkSync(getAuthPath());
31
+ }
32
+ catch {
33
+ // Ignore if file doesn't exist
34
+ }
35
+ }
36
+ export async function promptForApiKey() {
37
+ const stdin = process.stdin;
38
+ if (!stdin.isTTY) {
39
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
40
+ return new Promise((resolve) => {
41
+ rl.question("\n Enter your Command Code API key: ", (a) => {
42
+ rl.close();
43
+ resolve(a.trim());
44
+ });
45
+ });
46
+ }
47
+ return new Promise((resolve) => {
48
+ stdin.setRawMode(true);
49
+ stdin.resume();
50
+ let input = "";
51
+ process.stdout.write("\n Enter your Command Code API key: ");
52
+ const onData = (chunk) => {
53
+ const char = chunk.toString();
54
+ if (char === "\r" || char === "\n") {
55
+ stdin.setRawMode(false);
56
+ stdin.pause();
57
+ stdin.removeListener("data", onData);
58
+ process.stdout.write("\n");
59
+ resolve(input);
60
+ }
61
+ else if (char === "\x7f" || char === "\b") {
62
+ if (input.length > 0) {
63
+ input = input.slice(0, -1);
64
+ }
65
+ }
66
+ else if (char === "\x03") {
67
+ stdin.setRawMode(false);
68
+ process.exit(0);
69
+ }
70
+ else {
71
+ input += char;
72
+ }
73
+ };
74
+ stdin.on("data", onData);
75
+ });
76
+ }
77
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface Config {
2
+ host: string;
3
+ port: number;
4
+ apiKey: string | null;
5
+ ccApiBase: string;
6
+ ccVersion: string;
7
+ logLevel: string;
8
+ }
9
+ /**
10
+ * Hardcoded CLI version fallback. The real CLI ships frequent releases, so
11
+ * `fetchLatestCliVersion()` should be used to refresh this at startup. CC's
12
+ * server actively blocks requests whose version looks stale or absent.
13
+ */
14
+ export declare const DEFAULT_CC_VERSION = "0.40.3";
15
+ /**
16
+ * Fetch the latest published `command-code` CLI version from the npm registry.
17
+ * Returns `null` on any failure (caller falls back to DEFAULT_CC_VERSION).
18
+ * Cached for CC_VERSION_REFRESH_MS.
19
+ */
20
+ export declare function fetchLatestCliVersion(): Promise<string | null>;
21
+ export declare function loadConfig(): Config;
22
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAM3C;;;;GAIG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmBpE;AAqBD,wBAAgB,UAAU,IAAI,MAAM,CAWnC"}
package/dist/config.js ADDED
@@ -0,0 +1,67 @@
1
+ import { readAuthKey } from "./auth.js";
2
+ /**
3
+ * Hardcoded CLI version fallback. The real CLI ships frequent releases, so
4
+ * `fetchLatestCliVersion()` should be used to refresh this at startup. CC's
5
+ * server actively blocks requests whose version looks stale or absent.
6
+ */
7
+ export const DEFAULT_CC_VERSION = "0.40.3";
8
+ const CC_VERSION_REFRESH_MS = 24 * 60 * 60 * 1000;
9
+ let cachedVersion = null;
10
+ let lastFetchAt = 0;
11
+ /**
12
+ * Fetch the latest published `command-code` CLI version from the npm registry.
13
+ * Returns `null` on any failure (caller falls back to DEFAULT_CC_VERSION).
14
+ * Cached for CC_VERSION_REFRESH_MS.
15
+ */
16
+ export async function fetchLatestCliVersion() {
17
+ if (cachedVersion && Date.now() - lastFetchAt < CC_VERSION_REFRESH_MS) {
18
+ return cachedVersion;
19
+ }
20
+ try {
21
+ const res = await fetch("https://registry.npmjs.org/command-code/latest", {
22
+ signal: AbortSignal.timeout(10_000),
23
+ });
24
+ if (!res.ok)
25
+ return null;
26
+ const pkg = (await res.json());
27
+ if (pkg.version && typeof pkg.version === "string") {
28
+ cachedVersion = pkg.version;
29
+ lastFetchAt = Date.now();
30
+ return cachedVersion;
31
+ }
32
+ return null;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ function parseCliArgs() {
39
+ const args = process.argv.slice(2);
40
+ const map = {};
41
+ for (let i = 0; i < args.length; i++) {
42
+ const arg = args[i];
43
+ if (arg.startsWith("--")) {
44
+ const key = arg.slice(2);
45
+ const val = args[i + 1];
46
+ if (val && !val.startsWith("--")) {
47
+ map[key] = val;
48
+ i++;
49
+ }
50
+ else {
51
+ map[key] = true;
52
+ }
53
+ }
54
+ }
55
+ return map;
56
+ }
57
+ export function loadConfig() {
58
+ const cli = parseCliArgs();
59
+ const host = cli.host || process.env.HOST || "127.0.0.1";
60
+ const port = parseInt(cli.port || process.env.PORT || "8787", 10);
61
+ const apiKey = cli["api-key"] || process.env.CC_API_KEY || readAuthKey();
62
+ const ccApiBase = process.env.CC_API_BASE || "https://api.commandcode.ai";
63
+ const ccVersion = process.env.CC_CLI_VERSION || cachedVersion || DEFAULT_CC_VERSION;
64
+ const logLevel = process.env.LOG_LEVEL || "info";
65
+ return { host, port, apiKey, ccApiBase, ccVersion, logLevel };
66
+ }
67
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAkBxC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAC3C,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAElD,IAAI,aAAa,GAAkB,IAAI,CAAC;AACxC,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,IAAI,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,GAAG,qBAAqB,EAAE,CAAC;QACtE,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gDAAgD,EAAE;YACxE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyB,CAAC;QACvD,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACnD,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC;YAC5B,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACzB,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAY,EAAE,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,GAA0C,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;gBACvD,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,CAAC;gBACL,GAA+B,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAE3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC;IACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW,EAAE,CAAC;IACzE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,4BAA4B,CAAC;IAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,aAAa,IAAI,kBAAkB,CAAC;IACpF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;IAEjD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAChE,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ export declare function initLogger(level: string): void;
3
+ export declare const logger: {
4
+ debug(msg: string, ...args: unknown[]): void;
5
+ info(msg: string, ...args: unknown[]): void;
6
+ warn(msg: string, ...args: unknown[]): void;
7
+ error(msg: string, ...args: unknown[]): void;
8
+ };
9
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAW3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK9C;AAED,eAAO,MAAM,MAAM;eACN,MAAM,WAAW,OAAO,EAAE;cAK3B,MAAM,WAAW,OAAO,EAAE;cAK1B,MAAM,WAAW,OAAO,EAAE;eAKzB,MAAM,WAAW,OAAO,EAAE;CAKtC,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,36 @@
1
+ const LOG_LEVELS = {
2
+ debug: 0,
3
+ info: 1,
4
+ warn: 2,
5
+ error: 3,
6
+ };
7
+ let currentLogLevel = 1; // default to info
8
+ export function initLogger(level) {
9
+ const normalized = level.toLowerCase();
10
+ if (normalized in LOG_LEVELS) {
11
+ currentLogLevel = LOG_LEVELS[normalized];
12
+ }
13
+ }
14
+ export const logger = {
15
+ debug(msg, ...args) {
16
+ if (currentLogLevel <= LOG_LEVELS.debug) {
17
+ console.log(`[DEBUG] ${msg}`, ...args);
18
+ }
19
+ },
20
+ info(msg, ...args) {
21
+ if (currentLogLevel <= LOG_LEVELS.info) {
22
+ console.log(`[INFO] ${msg}`, ...args);
23
+ }
24
+ },
25
+ warn(msg, ...args) {
26
+ if (currentLogLevel <= LOG_LEVELS.warn) {
27
+ console.warn(`[WARN] ${msg}`, ...args);
28
+ }
29
+ },
30
+ error(msg, ...args) {
31
+ if (currentLogLevel <= LOG_LEVELS.error) {
32
+ console.error(`[ERROR] ${msg}`, ...args);
33
+ }
34
+ },
35
+ };
36
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAA6B;IAC3C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,IAAI,eAAe,GAAG,CAAC,CAAC,CAAC,kBAAkB;AAE3C,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAc,CAAC;IACnD,IAAI,UAAU,IAAI,UAAU,EAAE,CAAC;QAC7B,eAAe,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,eAAe,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,IAAI,eAAe,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,IAAI,eAAe,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IACD,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,eAAe,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,89 @@
1
+ {
2
+ "builtin": [
3
+ "deepseek/deepseek-v4-pro",
4
+ "deepseek/deepseek-v4-flash",
5
+ "MiniMaxAI/MiniMax-M2.7",
6
+ "MiniMaxAI/MiniMax-M2.5",
7
+ "zai-org/GLM-5.1",
8
+ "zai-org/GLM-5",
9
+ "moonshotai/Kimi-K2.6",
10
+ "moonshotai/Kimi-K2.5",
11
+ "Qwen/Qwen3.6-Max-Preview",
12
+ "Qwen/Qwen3.6-Plus",
13
+ "stepfun/Step-3.5-Flash",
14
+ "xiaomi/mimo-v2.5",
15
+ "Qwen/Qwen3.7-Max",
16
+ "Qwen/Qwen3.7-Plus"
17
+ ],
18
+ "shortAliases": {
19
+ "deepseek-v4-pro": "deepseek/deepseek-v4-pro",
20
+ "deepseek-v4": "deepseek/deepseek-v4-pro",
21
+ "deepseek-pro": "deepseek/deepseek-v4-pro",
22
+ "deepseek-v4-flash": "deepseek/deepseek-v4-flash",
23
+ "deepseek-flash": "deepseek/deepseek-v4-flash",
24
+ "kimi-k2.6": "moonshotai/Kimi-K2.6",
25
+ "kimi-k2.5": "moonshotai/Kimi-K2.5",
26
+ "kimi2.6": "moonshotai/Kimi-K2.6",
27
+ "kimi2.5": "moonshotai/Kimi-K2.5",
28
+ "glm-5.1": "zai-org/GLM-5.1",
29
+ "glm-5": "zai-org/GLM-5",
30
+ "minimax-m2.7": "MiniMaxAI/MiniMax-M2.7",
31
+ "minimax2.7": "MiniMaxAI/MiniMax-M2.7",
32
+ "minimax-m2.5": "MiniMaxAI/MiniMax-M2.5",
33
+ "minimax2.5": "MiniMaxAI/MiniMax-M2.5",
34
+ "qwen-3.6-max": "Qwen/Qwen3.6-Max-Preview",
35
+ "qwen3.6-max": "Qwen/Qwen3.6-Max-Preview",
36
+ "qwen-3.6-plus": "Qwen/Qwen3.6-Plus",
37
+ "qwen3.6-plus": "Qwen/Qwen3.6-Plus",
38
+ "step-3.5-flash": "stepfun/Step-3.5-Flash",
39
+ "step3.5": "stepfun/Step-3.5-Flash"
40
+ },
41
+ "contextWindows": {
42
+ "deepseek/deepseek-v4-pro": 1048576,
43
+ "deepseek/deepseek-v4-flash": 1048576,
44
+ "MiniMaxAI/MiniMax-M2.7": 204800,
45
+ "MiniMaxAI/MiniMax-M2.5": 204800,
46
+ "zai-org/GLM-5.1": 200000,
47
+ "zai-org/GLM-5": 200000,
48
+ "moonshotai/Kimi-K2.6": 262144,
49
+ "moonshotai/Kimi-K2.5": 262144,
50
+ "Qwen/Qwen3.6-Max-Preview": 262144,
51
+ "Qwen/Qwen3.6-Plus": 1048576,
52
+ "stepfun/Step-3.5-Flash": 262144,
53
+ "xiaomi/mimo-v2.5": 1048576,
54
+ "Qwen/Qwen3.7-Max": 1048576,
55
+ "Qwen/Qwen3.7-Plus": 1048576
56
+ },
57
+ "modelNames": {
58
+ "deepseek/deepseek-v4-pro": "DeepSeek V4 Pro",
59
+ "deepseek/deepseek-v4-flash": "DeepSeek V4 Flash",
60
+ "MiniMaxAI/MiniMax-M2.7": "MiniMax M2.7",
61
+ "MiniMaxAI/MiniMax-M2.5": "MiniMax M2.5",
62
+ "zai-org/GLM-5.1": "GLM-5.1",
63
+ "zai-org/GLM-5": "GLM-5",
64
+ "moonshotai/Kimi-K2.6": "Kimi K2.6",
65
+ "moonshotai/Kimi-K2.5": "Kimi K2.5",
66
+ "Qwen/Qwen3.6-Max-Preview": "Qwen 3.6 Max Preview",
67
+ "Qwen/Qwen3.6-Plus": "Qwen 3.6 Plus",
68
+ "stepfun/Step-3.5-Flash": "Step 3.5 Flash",
69
+ "xiaomi/mimo-v2.5": "MiMo V2.5",
70
+ "Qwen/Qwen3.7-Max": "Qwen 3.7 Max",
71
+ "Qwen/Qwen3.7-Plus": "Qwen 3.7 Plus"
72
+ },
73
+ "maxOutputTokens": {
74
+ "deepseek/deepseek-v4-pro": 393216,
75
+ "deepseek/deepseek-v4-flash": 393216,
76
+ "MiniMaxAI/MiniMax-M2.7": 32768,
77
+ "MiniMaxAI/MiniMax-M2.5": 32768,
78
+ "zai-org/GLM-5.1": 131072,
79
+ "zai-org/GLM-5": 131072,
80
+ "moonshotai/Kimi-K2.6": 98304,
81
+ "moonshotai/Kimi-K2.5": 98304,
82
+ "Qwen/Qwen3.6-Max-Preview": 65536,
83
+ "Qwen/Qwen3.6-Plus": 65536,
84
+ "stepfun/Step-3.5-Flash": 65536,
85
+ "xiaomi/mimo-v2.5": 131072,
86
+ "Qwen/Qwen3.7-Max": 65536,
87
+ "Qwen/Qwen3.7-Plus": 65536
88
+ }
89
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":""}
package/dist/proxy.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import { loadConfig, fetchLatestCliVersion } from "./config.js";
3
+ import { createServer } from "./server.js";
4
+ import { saveApiKey, promptForApiKey, readAuthKey, deleteAuth } from "./auth.js";
5
+ import { setupOpenCodeConfig } from "./setup/opencode.js";
6
+ import { logger, initLogger } from "./logger.js";
7
+ const args = process.argv.slice(2);
8
+ if (args[0] === "auth") {
9
+ const sub = args[1];
10
+ if (sub === "login") {
11
+ const force = args.includes("--force");
12
+ const existing = readAuthKey();
13
+ if (existing && !force) {
14
+ console.log("\n You are already logged in. Use `auth login --force` to overwrite.\n");
15
+ process.exit(0);
16
+ }
17
+ console.log("\n Get your API key from https://commandcode.ai/settings\n");
18
+ const key = await promptForApiKey();
19
+ if (!key) {
20
+ console.error(" FATAL: API key is required.\n");
21
+ process.exit(1);
22
+ }
23
+ saveApiKey(key);
24
+ console.log(" ✓ API key saved to ~/.config/commandcode-api-proxy/auth.json\n");
25
+ }
26
+ else if (sub === "logout") {
27
+ deleteAuth();
28
+ console.log("\n ✓ API key removed\n");
29
+ }
30
+ else {
31
+ console.error("\n Usage: commandcode-api-proxy auth <login|logout>\n");
32
+ }
33
+ process.exit(0);
34
+ }
35
+ if (args.includes("--setup-opencode")) {
36
+ await setupOpenCodeConfig();
37
+ process.exit(0);
38
+ }
39
+ const config = loadConfig();
40
+ initLogger(config.logLevel);
41
+ logger.info(`API key source: ${process.env.CC_API_KEY ? "env CC_API_KEY" : config.apiKey ? "auth.json" : "none"} (length: ${config.apiKey?.length ?? 0})`);
42
+ if (!process.env.CC_CLI_VERSION) {
43
+ const latest = await fetchLatestCliVersion();
44
+ if (latest)
45
+ config.ccVersion = latest;
46
+ }
47
+ if (!config.apiKey) {
48
+ console.log("\n No Command Code API key found.");
49
+ console.log(" You can get one from https://commandcode.ai/settings\n");
50
+ const key = await promptForApiKey();
51
+ if (!key) {
52
+ console.error(" FATAL: API key is required.\n");
53
+ process.exit(1);
54
+ }
55
+ saveApiKey(key);
56
+ config.apiKey = key;
57
+ console.log(" ✓ API key saved to ~/.config/commandcode-api-proxy/auth.json\n");
58
+ }
59
+ const server = createServer(config);
60
+ server.listen(config.port, config.host, () => {
61
+ console.log(`\n Command Code API Proxy v${process.env.npm_package_version ?? "0.1.0"}`);
62
+ console.log(` ${"=".repeat(50)}`);
63
+ console.log(` Listening on http://${config.host}:${config.port}`);
64
+ console.log(` Auth: ${config.apiKey ? "ENABLED (Bearer token or x-api-key)" : "DISABLED"}`);
65
+ console.log("");
66
+ console.log(" Endpoints:");
67
+ console.log(" GET /health");
68
+ console.log(" GET /v1/models");
69
+ console.log(" POST /v1/chat/completions (OpenAI format)");
70
+ console.log("");
71
+ console.log(" Press Ctrl+C to stop\n");
72
+ });
73
+ process.on("SIGINT", () => {
74
+ console.log("\n Shutting down...");
75
+ server.close(() => process.exit(0));
76
+ });
77
+ process.on("SIGTERM", () => {
78
+ server.close(() => process.exit(0));
79
+ });
80
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import http from "node:http";
2
+ import type { Config } from "./config.js";
3
+ export declare function createServer(cfg: Config): http.Server;
4
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiQ1C,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAsDrD"}