copilot-api-plus 1.0.5 → 1.0.7
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.
- package/README.md +271 -0
- package/dist/auth-C5zV8JbW.js +73 -0
- package/dist/auth-C5zV8JbW.js.map +1 -0
- package/dist/auth-KlL1W4gV.js +4 -0
- package/dist/error-CsShqJjE.js +3 -0
- package/dist/{error-Cmeg4mmB.js → error-CvU5otz-.js} +1 -1
- package/dist/{error-Cmeg4mmB.js.map → error-CvU5otz-.js.map} +1 -1
- package/dist/get-models-Hlxa1hWY.js +33 -0
- package/dist/get-models-Hlxa1hWY.js.map +1 -0
- package/dist/{get-user-DalX7epg.js → get-user-DgPgvnrS.js} +4 -12
- package/dist/{get-user-DalX7epg.js.map → get-user-DgPgvnrS.js.map} +1 -1
- package/dist/get-user-M3sQS0U8.js +5 -0
- package/dist/main.js +289 -44
- package/dist/main.js.map +1 -1
- package/dist/paths-Ch0ixSo2.js +28 -0
- package/dist/paths-Ch0ixSo2.js.map +1 -0
- package/dist/state-DAw5jMjc.js +12 -0
- package/dist/state-DAw5jMjc.js.map +1 -0
- package/dist/token-BssxOyqn.js +7 -0
- package/dist/{token-CRn8c1A7.js → token-DYeOMeid.js} +6 -27
- package/dist/token-DYeOMeid.js.map +1 -0
- package/package.json +5 -3
- package/dist/error-Ba4dbGYj.js +0 -3
- package/dist/get-user-BQgLIPYd.js +0 -4
- package/dist/token-CRn8c1A7.js.map +0 -1
- package/dist/token-DP4tvNfm.js +0 -5
package/dist/main.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { PATHS,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { PATHS, ensurePaths } from "./paths-Ch0ixSo2.js";
|
|
3
|
+
import { state } from "./state-DAw5jMjc.js";
|
|
4
|
+
import { GITHUB_API_BASE_URL, copilotBaseUrl, copilotHeaders, githubHeaders } from "./get-user-DgPgvnrS.js";
|
|
5
|
+
import { HTTPError, forwardError } from "./error-CvU5otz-.js";
|
|
6
|
+
import { cacheModels, cacheVSCodeVersion, clearGithubToken, isNullish, setupCopilotToken, setupGitHubToken, sleep } from "./token-DYeOMeid.js";
|
|
7
|
+
import { clearZenAuth, getZenAuthPath } from "./auth-C5zV8JbW.js";
|
|
5
8
|
import { defineCommand, runMain } from "citty";
|
|
6
9
|
import consola from "consola";
|
|
7
10
|
import fs from "node:fs/promises";
|
|
@@ -177,19 +180,68 @@ const debug = defineCommand({
|
|
|
177
180
|
|
|
178
181
|
//#endregion
|
|
179
182
|
//#region src/logout.ts
|
|
180
|
-
async function runLogout() {
|
|
183
|
+
async function runLogout(options) {
|
|
181
184
|
await ensurePaths();
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
+
if (options.all) {
|
|
186
|
+
await clearGithubToken();
|
|
187
|
+
await clearZenAuth();
|
|
188
|
+
consola.success("Logged out from all services");
|
|
189
|
+
consola.info(`GitHub token: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
190
|
+
consola.info(`Zen API key: ${getZenAuthPath()}`);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (options.zen) {
|
|
194
|
+
await clearZenAuth();
|
|
195
|
+
consola.success("Logged out from OpenCode Zen");
|
|
196
|
+
consola.info(`Zen API key location: ${getZenAuthPath()}`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const choice = await consola.prompt("Which credentials do you want to clear?", {
|
|
200
|
+
type: "select",
|
|
201
|
+
options: [
|
|
202
|
+
"GitHub Copilot token",
|
|
203
|
+
"OpenCode Zen API key",
|
|
204
|
+
"Both (all credentials)"
|
|
205
|
+
]
|
|
206
|
+
});
|
|
207
|
+
if (choice === "GitHub Copilot token") {
|
|
208
|
+
await clearGithubToken();
|
|
209
|
+
consola.success("Logged out from GitHub Copilot");
|
|
210
|
+
consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
211
|
+
} else if (choice === "OpenCode Zen API key") {
|
|
212
|
+
await clearZenAuth();
|
|
213
|
+
consola.success("Logged out from OpenCode Zen");
|
|
214
|
+
consola.info(`Zen API key location: ${getZenAuthPath()}`);
|
|
215
|
+
} else if (choice === "Both (all credentials)") {
|
|
216
|
+
await clearGithubToken();
|
|
217
|
+
await clearZenAuth();
|
|
218
|
+
consola.success("Logged out from all services");
|
|
219
|
+
}
|
|
185
220
|
}
|
|
186
221
|
const logout = defineCommand({
|
|
187
222
|
meta: {
|
|
188
223
|
name: "logout",
|
|
189
|
-
description: "Clear stored
|
|
224
|
+
description: "Clear stored credentials and logout"
|
|
190
225
|
},
|
|
191
|
-
|
|
192
|
-
|
|
226
|
+
args: {
|
|
227
|
+
zen: {
|
|
228
|
+
alias: "z",
|
|
229
|
+
type: "boolean",
|
|
230
|
+
default: false,
|
|
231
|
+
description: "Clear only OpenCode Zen API key"
|
|
232
|
+
},
|
|
233
|
+
all: {
|
|
234
|
+
alias: "a",
|
|
235
|
+
type: "boolean",
|
|
236
|
+
default: false,
|
|
237
|
+
description: "Clear all credentials (GitHub and Zen)"
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
run({ args }) {
|
|
241
|
+
return runLogout({
|
|
242
|
+
zen: args.zen,
|
|
243
|
+
all: args.all
|
|
244
|
+
});
|
|
193
245
|
}
|
|
194
246
|
});
|
|
195
247
|
|
|
@@ -688,6 +740,14 @@ function translateModelName(model) {
|
|
|
688
740
|
if (supportedModels.includes(modelWithDot)) return modelWithDot;
|
|
689
741
|
const modelWithDash = model.replace(/(\d+)\.(\d+)/, "$1-$2");
|
|
690
742
|
if (supportedModels.includes(modelWithDash)) return modelWithDash;
|
|
743
|
+
for (const [oldFormat, newFormat] of Object.entries({
|
|
744
|
+
"claude-3-5-sonnet": "claude-sonnet-4.5",
|
|
745
|
+
"claude-3-sonnet": "claude-sonnet-4",
|
|
746
|
+
"claude-3-5-opus": "claude-opus-4.5",
|
|
747
|
+
"claude-3-opus": "claude-opus-4.5",
|
|
748
|
+
"claude-3-5-haiku": "claude-haiku-4.5",
|
|
749
|
+
"claude-3-haiku": "claude-haiku-4.5"
|
|
750
|
+
})) if (modelBase.startsWith(oldFormat) && supportedModels.includes(newFormat)) return newFormat;
|
|
691
751
|
const modelFamily = model.includes("opus") ? "opus" : model.includes("sonnet") ? "sonnet" : model.includes("haiku") ? "haiku" : null;
|
|
692
752
|
if (modelFamily) {
|
|
693
753
|
const familyModel = supportedModels.find((m) => m.includes(modelFamily));
|
|
@@ -1021,11 +1081,8 @@ function translateChunkToAnthropicEvents(chunk, state$1) {
|
|
|
1021
1081
|
async function handleCompletion(c) {
|
|
1022
1082
|
await checkRateLimit(state);
|
|
1023
1083
|
const anthropicPayload = await c.req.json();
|
|
1024
|
-
consola.info(`[Messages] Received model: "${anthropicPayload.model}"`);
|
|
1025
1084
|
consola.debug("Anthropic request payload:", JSON.stringify(anthropicPayload));
|
|
1026
1085
|
const openAIPayload = translateToOpenAI(anthropicPayload);
|
|
1027
|
-
consola.info(`[Messages] Translated to: "${openAIPayload.model}"`);
|
|
1028
|
-
consola.info(`[Messages] Available models: ${state.models?.data.map((m) => m.id).join(", ") ?? "none"}`);
|
|
1029
1086
|
consola.debug("Translated OpenAI request payload:", JSON.stringify(openAIPayload));
|
|
1030
1087
|
if (state.manualApprove) await awaitApproval();
|
|
1031
1088
|
const response = await createChatCompletions(openAIPayload);
|
|
@@ -1132,6 +1189,142 @@ usageRoute.get("/", async (c) => {
|
|
|
1132
1189
|
}
|
|
1133
1190
|
});
|
|
1134
1191
|
|
|
1192
|
+
//#endregion
|
|
1193
|
+
//#region src/services/zen/create-chat-completions.ts
|
|
1194
|
+
/**
|
|
1195
|
+
* Create chat completions via OpenCode Zen
|
|
1196
|
+
*/
|
|
1197
|
+
async function createZenChatCompletions(request, signal) {
|
|
1198
|
+
const apiKey = state.zenApiKey;
|
|
1199
|
+
if (!apiKey) throw new Error("Zen API key not configured");
|
|
1200
|
+
consola.debug(`Zen chat completions request for model: ${request.model}`);
|
|
1201
|
+
const response = await fetch("https://opencode.ai/zen/v1/chat/completions", {
|
|
1202
|
+
method: "POST",
|
|
1203
|
+
headers: {
|
|
1204
|
+
"Content-Type": "application/json",
|
|
1205
|
+
Authorization: `Bearer ${apiKey}`
|
|
1206
|
+
},
|
|
1207
|
+
body: JSON.stringify(request),
|
|
1208
|
+
signal
|
|
1209
|
+
});
|
|
1210
|
+
if (!response.ok) {
|
|
1211
|
+
const errorText = await response.text();
|
|
1212
|
+
consola.error(`Zen API error: ${response.status} ${errorText}`);
|
|
1213
|
+
throw new Error(`Zen API error: ${response.status} ${errorText}`);
|
|
1214
|
+
}
|
|
1215
|
+
return response;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
//#endregion
|
|
1219
|
+
//#region src/routes/zen/chat-completions/route.ts
|
|
1220
|
+
const zenCompletionRoutes = new Hono();
|
|
1221
|
+
zenCompletionRoutes.post("/", async (c) => {
|
|
1222
|
+
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
1223
|
+
try {
|
|
1224
|
+
const body = await c.req.json();
|
|
1225
|
+
consola.debug("Zen chat completion request:", body.model);
|
|
1226
|
+
const response = await createZenChatCompletions(body);
|
|
1227
|
+
if (body.stream) {
|
|
1228
|
+
const headers = new Headers();
|
|
1229
|
+
headers.set("Content-Type", "text/event-stream");
|
|
1230
|
+
headers.set("Cache-Control", "no-cache");
|
|
1231
|
+
headers.set("Connection", "keep-alive");
|
|
1232
|
+
return new Response(response.body, {
|
|
1233
|
+
status: response.status,
|
|
1234
|
+
headers
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
const data = await response.json();
|
|
1238
|
+
return c.json(data);
|
|
1239
|
+
} catch (error) {
|
|
1240
|
+
consola.error("Zen chat completion error:", error);
|
|
1241
|
+
return c.json({ error: {
|
|
1242
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
1243
|
+
type: "zen_error"
|
|
1244
|
+
} }, 500);
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
//#endregion
|
|
1249
|
+
//#region src/services/zen/create-messages.ts
|
|
1250
|
+
/**
|
|
1251
|
+
* Create messages via OpenCode Zen (Anthropic format)
|
|
1252
|
+
*/
|
|
1253
|
+
async function createZenMessages(request, signal) {
|
|
1254
|
+
const apiKey = state.zenApiKey;
|
|
1255
|
+
if (!apiKey) throw new Error("Zen API key not configured");
|
|
1256
|
+
consola.debug(`Zen messages request for model: ${request.model}`);
|
|
1257
|
+
const response = await fetch("https://opencode.ai/zen/v1/messages", {
|
|
1258
|
+
method: "POST",
|
|
1259
|
+
headers: {
|
|
1260
|
+
"Content-Type": "application/json",
|
|
1261
|
+
"x-api-key": apiKey,
|
|
1262
|
+
"anthropic-version": "2023-06-01"
|
|
1263
|
+
},
|
|
1264
|
+
body: JSON.stringify(request),
|
|
1265
|
+
signal
|
|
1266
|
+
});
|
|
1267
|
+
if (!response.ok) {
|
|
1268
|
+
const errorText = await response.text();
|
|
1269
|
+
consola.error(`Zen Messages API error: ${response.status} ${errorText}`);
|
|
1270
|
+
throw new Error(`Zen Messages API error: ${response.status} ${errorText}`);
|
|
1271
|
+
}
|
|
1272
|
+
return response;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
//#endregion
|
|
1276
|
+
//#region src/routes/zen/messages/route.ts
|
|
1277
|
+
const zenMessageRoutes = new Hono();
|
|
1278
|
+
zenMessageRoutes.post("/", async (c) => {
|
|
1279
|
+
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
1280
|
+
try {
|
|
1281
|
+
const body = await c.req.json();
|
|
1282
|
+
consola.debug("Zen message request:", body.model);
|
|
1283
|
+
const response = await createZenMessages(body);
|
|
1284
|
+
if (body.stream) {
|
|
1285
|
+
const headers = new Headers();
|
|
1286
|
+
headers.set("Content-Type", "text/event-stream");
|
|
1287
|
+
headers.set("Cache-Control", "no-cache");
|
|
1288
|
+
headers.set("Connection", "keep-alive");
|
|
1289
|
+
return new Response(response.body, {
|
|
1290
|
+
status: response.status,
|
|
1291
|
+
headers
|
|
1292
|
+
});
|
|
1293
|
+
}
|
|
1294
|
+
const data = await response.json();
|
|
1295
|
+
return c.json(data);
|
|
1296
|
+
} catch (error) {
|
|
1297
|
+
consola.error("Zen message error:", error);
|
|
1298
|
+
return c.json({
|
|
1299
|
+
type: "error",
|
|
1300
|
+
error: {
|
|
1301
|
+
type: "zen_error",
|
|
1302
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
1303
|
+
}
|
|
1304
|
+
}, 500);
|
|
1305
|
+
}
|
|
1306
|
+
});
|
|
1307
|
+
|
|
1308
|
+
//#endregion
|
|
1309
|
+
//#region src/routes/zen/models/route.ts
|
|
1310
|
+
const zenModelRoutes = new Hono();
|
|
1311
|
+
zenModelRoutes.get("/", async (c) => {
|
|
1312
|
+
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
1313
|
+
try {
|
|
1314
|
+
if (state.zenModels) return c.json(state.zenModels);
|
|
1315
|
+
const { getZenModels } = await import("./get-models-Hlxa1hWY.js");
|
|
1316
|
+
const models = await getZenModels();
|
|
1317
|
+
state.zenModels = models;
|
|
1318
|
+
return c.json(models);
|
|
1319
|
+
} catch (error) {
|
|
1320
|
+
consola.error("Zen models error:", error);
|
|
1321
|
+
return c.json({ error: {
|
|
1322
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
1323
|
+
type: "zen_error"
|
|
1324
|
+
} }, 500);
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
|
|
1135
1328
|
//#endregion
|
|
1136
1329
|
//#region src/server.ts
|
|
1137
1330
|
const server = new Hono();
|
|
@@ -1139,15 +1332,33 @@ server.use(logger());
|
|
|
1139
1332
|
server.use(cors());
|
|
1140
1333
|
server.use(apiKeyAuthMiddleware);
|
|
1141
1334
|
server.get("/", (c) => c.text("Server running"));
|
|
1142
|
-
server.route("/chat/completions",
|
|
1143
|
-
|
|
1335
|
+
server.route("/chat/completions", new Hono().all("/*", async (c, next) => {
|
|
1336
|
+
if (state.zenMode) return zenCompletionRoutes.fetch(c.req.raw, c.env);
|
|
1337
|
+
return completionRoutes.fetch(c.req.raw, c.env);
|
|
1338
|
+
}));
|
|
1339
|
+
server.route("/models", new Hono().all("/*", async (c, next) => {
|
|
1340
|
+
if (state.zenMode) return zenModelRoutes.fetch(c.req.raw, c.env);
|
|
1341
|
+
return modelRoutes.fetch(c.req.raw, c.env);
|
|
1342
|
+
}));
|
|
1144
1343
|
server.route("/embeddings", embeddingRoutes);
|
|
1145
1344
|
server.route("/usage", usageRoute);
|
|
1146
1345
|
server.route("/token", tokenRoute);
|
|
1147
|
-
server.route("/v1/chat/completions",
|
|
1148
|
-
|
|
1346
|
+
server.route("/v1/chat/completions", new Hono().all("/*", async (c, next) => {
|
|
1347
|
+
if (state.zenMode) return zenCompletionRoutes.fetch(c.req.raw, c.env);
|
|
1348
|
+
return completionRoutes.fetch(c.req.raw, c.env);
|
|
1349
|
+
}));
|
|
1350
|
+
server.route("/v1/models", new Hono().all("/*", async (c, next) => {
|
|
1351
|
+
if (state.zenMode) return zenModelRoutes.fetch(c.req.raw, c.env);
|
|
1352
|
+
return modelRoutes.fetch(c.req.raw, c.env);
|
|
1353
|
+
}));
|
|
1149
1354
|
server.route("/v1/embeddings", embeddingRoutes);
|
|
1150
|
-
server.route("/v1/messages",
|
|
1355
|
+
server.route("/v1/messages", new Hono().all("/*", async (c, next) => {
|
|
1356
|
+
if (state.zenMode) return zenMessageRoutes.fetch(c.req.raw, c.env);
|
|
1357
|
+
return messageRoutes.fetch(c.req.raw, c.env);
|
|
1358
|
+
}));
|
|
1359
|
+
server.route("/zen/v1/chat/completions", zenCompletionRoutes);
|
|
1360
|
+
server.route("/zen/v1/models", zenModelRoutes);
|
|
1361
|
+
server.route("/zen/v1/messages", zenMessageRoutes);
|
|
1151
1362
|
|
|
1152
1363
|
//#endregion
|
|
1153
1364
|
//#region src/start.ts
|
|
@@ -1171,6 +1382,8 @@ server.route("/v1/messages", messageRoutes);
|
|
|
1171
1382
|
* - showToken: Expose GitHub/Copilot tokens in responses for debugging
|
|
1172
1383
|
* - proxyEnv: Initialize proxy settings from environment variables
|
|
1173
1384
|
* - apiKeys: Optional list of API keys to enable API key authentication
|
|
1385
|
+
* - zen: Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)
|
|
1386
|
+
* - zenApiKey: OpenCode Zen API key (optional; if omitted will prompt for setup)
|
|
1174
1387
|
*/
|
|
1175
1388
|
async function runServer(options) {
|
|
1176
1389
|
if (options.proxyEnv) initProxyFromEnv();
|
|
@@ -1187,43 +1400,63 @@ async function runServer(options) {
|
|
|
1187
1400
|
state.apiKeys = options.apiKeys;
|
|
1188
1401
|
if (state.apiKeys && state.apiKeys.length > 0) consola.info(`API key authentication enabled with ${state.apiKeys.length} key(s)`);
|
|
1189
1402
|
await ensurePaths();
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
state.
|
|
1193
|
-
|
|
1403
|
+
if (options.zen) {
|
|
1404
|
+
consola.info("OpenCode Zen mode enabled");
|
|
1405
|
+
state.zenMode = true;
|
|
1406
|
+
if (options.zenApiKey) {
|
|
1407
|
+
state.zenApiKey = options.zenApiKey;
|
|
1408
|
+
consola.info("Using provided Zen API key");
|
|
1409
|
+
} else {
|
|
1410
|
+
const { setupZenApiKey, loadZenAuth } = await import("./auth-KlL1W4gV.js");
|
|
1411
|
+
const existingAuth = await loadZenAuth();
|
|
1412
|
+
if (existingAuth) {
|
|
1413
|
+
state.zenApiKey = existingAuth.apiKey;
|
|
1414
|
+
consola.info("Using existing Zen API key");
|
|
1415
|
+
} else state.zenApiKey = await setupZenApiKey();
|
|
1416
|
+
}
|
|
1417
|
+
const { cacheZenModels } = await import("./get-models-Hlxa1hWY.js");
|
|
1418
|
+
await cacheZenModels();
|
|
1419
|
+
consola.info(`Available Zen models: \n${state.zenModels?.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
1420
|
+
} else {
|
|
1421
|
+
await cacheVSCodeVersion();
|
|
1422
|
+
if (options.githubToken) {
|
|
1423
|
+
state.githubToken = options.githubToken;
|
|
1424
|
+
consola.info("Using provided GitHub token");
|
|
1425
|
+
try {
|
|
1426
|
+
const { getGitHubUser } = await import("./get-user-M3sQS0U8.js");
|
|
1427
|
+
const user = await getGitHubUser();
|
|
1428
|
+
consola.info(`Logged in as ${user.login}`);
|
|
1429
|
+
} catch (error) {
|
|
1430
|
+
consola.error("Provided GitHub token is invalid");
|
|
1431
|
+
throw error;
|
|
1432
|
+
}
|
|
1433
|
+
} else await setupGitHubToken();
|
|
1194
1434
|
try {
|
|
1195
|
-
|
|
1196
|
-
const user = await getGitHubUser();
|
|
1197
|
-
consola.info(`Logged in as ${user.login}`);
|
|
1435
|
+
await setupCopilotToken();
|
|
1198
1436
|
} catch (error) {
|
|
1199
|
-
|
|
1437
|
+
const { HTTPError: HTTPError$1 } = await import("./error-CsShqJjE.js");
|
|
1438
|
+
if (error instanceof HTTPError$1 && error.response.status === 401) {
|
|
1439
|
+
consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
|
|
1440
|
+
const { clearGithubToken: clearGithubToken$1 } = await import("./token-BssxOyqn.js");
|
|
1441
|
+
await clearGithubToken$1();
|
|
1442
|
+
consola.info("Please restart to re-authenticate");
|
|
1443
|
+
}
|
|
1200
1444
|
throw error;
|
|
1201
1445
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
await setupCopilotToken();
|
|
1205
|
-
} catch (error) {
|
|
1206
|
-
const { HTTPError: HTTPError$1 } = await import("./error-Ba4dbGYj.js");
|
|
1207
|
-
if (error instanceof HTTPError$1 && error.response.status === 401) {
|
|
1208
|
-
consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
|
|
1209
|
-
const { clearGithubToken: clearGithubToken$1 } = await import("./token-DP4tvNfm.js");
|
|
1210
|
-
await clearGithubToken$1();
|
|
1211
|
-
consola.info("Please restart to re-authenticate");
|
|
1212
|
-
}
|
|
1213
|
-
throw error;
|
|
1446
|
+
await cacheModels();
|
|
1447
|
+
consola.info(`Available models: \n${state.models?.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
1214
1448
|
}
|
|
1215
|
-
await cacheModels();
|
|
1216
|
-
consola.info(`Available models: \n${state.models?.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
1217
1449
|
const serverUrl = `http://localhost:${options.port}`;
|
|
1218
1450
|
if (options.claudeCode) {
|
|
1219
|
-
|
|
1451
|
+
const models = state.zenMode ? state.zenModels : state.models;
|
|
1452
|
+
invariant(models, "Models should be loaded by now");
|
|
1220
1453
|
const selectedModel = await consola.prompt("Select a model to use with Claude Code", {
|
|
1221
1454
|
type: "select",
|
|
1222
|
-
options:
|
|
1455
|
+
options: models.data.map((model) => model.id)
|
|
1223
1456
|
});
|
|
1224
1457
|
const selectedSmallModel = await consola.prompt("Select a small model to use with Claude Code", {
|
|
1225
1458
|
type: "select",
|
|
1226
|
-
options:
|
|
1459
|
+
options: models.data.map((model) => model.id)
|
|
1227
1460
|
});
|
|
1228
1461
|
const command = generateEnvScript({
|
|
1229
1462
|
ANTHROPIC_BASE_URL: serverUrl,
|
|
@@ -1313,6 +1546,16 @@ const start = defineCommand({
|
|
|
1313
1546
|
"api-key": {
|
|
1314
1547
|
type: "string",
|
|
1315
1548
|
description: "API keys for authentication"
|
|
1549
|
+
},
|
|
1550
|
+
zen: {
|
|
1551
|
+
alias: "z",
|
|
1552
|
+
type: "boolean",
|
|
1553
|
+
default: false,
|
|
1554
|
+
description: "Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)"
|
|
1555
|
+
},
|
|
1556
|
+
"zen-api-key": {
|
|
1557
|
+
type: "string",
|
|
1558
|
+
description: "OpenCode Zen API key (get from https://opencode.ai/zen)"
|
|
1316
1559
|
}
|
|
1317
1560
|
},
|
|
1318
1561
|
run({ args }) {
|
|
@@ -1332,7 +1575,9 @@ const start = defineCommand({
|
|
|
1332
1575
|
claudeCode: args["claude-code"],
|
|
1333
1576
|
showToken: args["show-token"],
|
|
1334
1577
|
proxyEnv: args["proxy-env"],
|
|
1335
|
-
apiKeys
|
|
1578
|
+
apiKeys,
|
|
1579
|
+
zen: args.zen,
|
|
1580
|
+
zenApiKey: args["zen-api-key"]
|
|
1336
1581
|
});
|
|
1337
1582
|
}
|
|
1338
1583
|
});
|