@mrciphersmith/keryx 0.2.100 → 0.2.102
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/dist/cli.js +191 -93
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -298,6 +298,91 @@ var init_provider_config = __esm(() => {
|
|
|
298
298
|
];
|
|
299
299
|
});
|
|
300
300
|
|
|
301
|
+
// src/lib/oauth/catalog.ts
|
|
302
|
+
function extraRequestHeaders(provider) {
|
|
303
|
+
if (provider === "github-copilot") {
|
|
304
|
+
return GITHUB_COPILOT_REQUEST_HEADERS;
|
|
305
|
+
}
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
function authCatalogEntry(provider) {
|
|
309
|
+
return PROVIDER_AUTH_CATALOG.find((entry) => entry.provider === provider);
|
|
310
|
+
}
|
|
311
|
+
function catalogMethods(provider) {
|
|
312
|
+
return authCatalogEntry(provider)?.methods ?? ["api-key"];
|
|
313
|
+
}
|
|
314
|
+
function catalogAllows(provider, method) {
|
|
315
|
+
return catalogMethods(provider).includes(method);
|
|
316
|
+
}
|
|
317
|
+
function catalogRefusal(provider) {
|
|
318
|
+
return authCatalogEntry(provider)?.refusal;
|
|
319
|
+
}
|
|
320
|
+
function deviceCodeMethodLabel(provider) {
|
|
321
|
+
if (provider === "grok")
|
|
322
|
+
return "SuperGrok Subscription";
|
|
323
|
+
if (provider === "github-copilot")
|
|
324
|
+
return "Login with GitHub Copilot";
|
|
325
|
+
if (provider === "openai")
|
|
326
|
+
return "ChatGPT Plus/Pro (headless)";
|
|
327
|
+
return "Device authorization";
|
|
328
|
+
}
|
|
329
|
+
var XAI_GROK_DEVICE, GITHUB_COPILOT_REQUEST_HEADERS, GITHUB_COPILOT_OAUTH_CLIENT_ID = "Iv1.b507a08c87ecfe98", GITHUB_COPILOT_DEVICE, PROVIDER_AUTH_CATALOG;
|
|
330
|
+
var init_catalog = __esm(() => {
|
|
331
|
+
XAI_GROK_DEVICE = {
|
|
332
|
+
deviceAuthorizationEndpoint: "https://auth.x.ai/oauth2/device/code",
|
|
333
|
+
tokenEndpoint: "https://auth.x.ai/oauth2/token",
|
|
334
|
+
clientId: "b1a00492-073a-47ea-816f-4c329264a828",
|
|
335
|
+
scope: "openid profile email offline_access grok-cli:access api:access",
|
|
336
|
+
extraForm: { referrer: "keryx" },
|
|
337
|
+
headers: { "User-Agent": "keryx" }
|
|
338
|
+
};
|
|
339
|
+
GITHUB_COPILOT_REQUEST_HEADERS = {
|
|
340
|
+
Accept: "application/json",
|
|
341
|
+
"User-Agent": "GitHubCopilotChat/0.26.7",
|
|
342
|
+
"Editor-Version": "vscode/1.99.3",
|
|
343
|
+
"Editor-Plugin-Version": "copilot-chat/0.26.7",
|
|
344
|
+
"Copilot-Integration-Id": "vscode-chat"
|
|
345
|
+
};
|
|
346
|
+
GITHUB_COPILOT_DEVICE = {
|
|
347
|
+
deviceAuthorizationEndpoint: "https://github.com/login/device/code",
|
|
348
|
+
tokenEndpoint: "https://github.com/login/oauth/access_token",
|
|
349
|
+
clientId: GITHUB_COPILOT_OAUTH_CLIENT_ID,
|
|
350
|
+
scope: "read:user",
|
|
351
|
+
headers: GITHUB_COPILOT_REQUEST_HEADERS,
|
|
352
|
+
afterToken: "github-copilot"
|
|
353
|
+
};
|
|
354
|
+
PROVIDER_AUTH_CATALOG = [
|
|
355
|
+
{
|
|
356
|
+
provider: "grok",
|
|
357
|
+
label: "xAI (Grok)",
|
|
358
|
+
methods: ["device-code", "api-key"],
|
|
359
|
+
device: XAI_GROK_DEVICE
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
provider: "openai",
|
|
363
|
+
label: "OpenAI",
|
|
364
|
+
methods: ["oauth-pkce-loopback", "device-code", "api-key"]
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
provider: "github-copilot",
|
|
368
|
+
label: "GitHub Copilot",
|
|
369
|
+
methods: ["device-code"],
|
|
370
|
+
device: GITHUB_COPILOT_DEVICE
|
|
371
|
+
},
|
|
372
|
+
{ provider: "anthropic", label: "Anthropic", methods: ["api-key"], refusal: "Anthropic does not permit third-party Claude Pro/Max login. Use an API key from the Anthropic Console." },
|
|
373
|
+
{ provider: "gemini", label: "Google Gemini", methods: ["api-key"], refusal: "Gemini Google-account login is for Gemini CLI. In keryx use GEMINI_API_KEY from Google AI Studio." },
|
|
374
|
+
{ provider: "deepseek", label: "DeepSeek", methods: ["api-key"], refusal: "DeepSeek has no consumer OAuth grant. Use DEEPSEEK_API_KEY." },
|
|
375
|
+
{ provider: "openrouter", label: "OpenRouter", methods: ["api-key"] },
|
|
376
|
+
{ provider: "zai", label: "Z.AI (GLM)", methods: ["api-key"] },
|
|
377
|
+
{ provider: "zai-coding", label: "Z.AI GLM Coding Plan", methods: ["api-key"] },
|
|
378
|
+
{ provider: "cerebras", label: "Cerebras", methods: ["api-key"] },
|
|
379
|
+
{ provider: "groq", label: "Groq", methods: ["api-key"] },
|
|
380
|
+
{ provider: "moonshot", label: "Moonshot (Kimi)", methods: ["api-key"] },
|
|
381
|
+
{ provider: "ollama", label: "Ollama", methods: ["none"] },
|
|
382
|
+
{ provider: "rapid-mlx", label: "Rapid-MLX (Local)", methods: ["none"] }
|
|
383
|
+
];
|
|
384
|
+
});
|
|
385
|
+
|
|
301
386
|
// src/lib/shell-config.ts
|
|
302
387
|
import { existsSync as existsSync2 } from "fs";
|
|
303
388
|
import path3 from "path";
|
|
@@ -641,8 +726,13 @@ async function fetchOpenAiCompatModelsDetailed(fetchFn, provider, apiKey, opts)
|
|
|
641
726
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
642
727
|
try {
|
|
643
728
|
const init = { signal: controller.signal };
|
|
729
|
+
const extraHeaders = extraRequestHeaders(provider.name);
|
|
730
|
+
const headers = extraHeaders === undefined ? {} : { ...extraHeaders };
|
|
644
731
|
if (apiKey !== undefined && apiKey.length > 0) {
|
|
645
|
-
|
|
732
|
+
headers.authorization = `Bearer ${apiKey}`;
|
|
733
|
+
}
|
|
734
|
+
if (Object.keys(headers).length > 0) {
|
|
735
|
+
init.headers = headers;
|
|
646
736
|
}
|
|
647
737
|
const res = await fetchFn(url, init);
|
|
648
738
|
if (!res.ok) {
|
|
@@ -890,6 +980,7 @@ with a stated reason and exits 0 \u2014 that is a normal configuration, not an e
|
|
|
890
980
|
var DEFAULT_MODELS_PATH = "/v1/models", OPENAI_COMPAT_PROVIDERS, MODELS_FETCH_TIMEOUT_MS = 1e4, MODELS_ERROR_BODY_LIMIT = 4096, BALANCE_FETCH_TIMEOUT_MS = 8000;
|
|
891
981
|
var init_providers = __esm(() => {
|
|
892
982
|
init_provider_config();
|
|
983
|
+
init_catalog();
|
|
893
984
|
init_grants();
|
|
894
985
|
init_shell_config();
|
|
895
986
|
init_args();
|
|
@@ -998,6 +1089,8 @@ var init_providers = __esm(() => {
|
|
|
998
1089
|
label: "GitHub Copilot",
|
|
999
1090
|
baseUrl: "https://api.githubcopilot.com",
|
|
1000
1091
|
envKey: "GITHUB_COPILOT_TOKEN",
|
|
1092
|
+
chatPath: "/chat/completions",
|
|
1093
|
+
modelsPath: "/models",
|
|
1001
1094
|
models: ["gpt-4o", "gpt-4.1", "gpt-4o-mini"],
|
|
1002
1095
|
note: "Copilot \xB7 device login"
|
|
1003
1096
|
}
|
|
@@ -8310,6 +8403,7 @@ function makeProvider(name, _model, opts) {
|
|
|
8310
8403
|
if (needsKey && (apiKey === undefined || apiKey.length === 0)) {
|
|
8311
8404
|
return new FakeProvider([]);
|
|
8312
8405
|
}
|
|
8406
|
+
const extraHeaders = extraRequestHeaders(name);
|
|
8313
8407
|
const grant = {
|
|
8314
8408
|
network: true,
|
|
8315
8409
|
...compat.streamUsage === true ? { streamUsage: true } : {},
|
|
@@ -8317,7 +8411,8 @@ function makeProvider(name, _model, opts) {
|
|
|
8317
8411
|
...compat.allowLoopback === true ? { allowLoopback: true } : {},
|
|
8318
8412
|
...compat.allowPrivateLan === true ? { allowPrivateLan: true } : {},
|
|
8319
8413
|
...compat.chatPath !== undefined ? { chatPath: compat.chatPath } : {},
|
|
8320
|
-
...apiKey !== undefined ? { apiKey } : {}
|
|
8414
|
+
...apiKey !== undefined ? { apiKey } : {},
|
|
8415
|
+
...extraHeaders !== undefined ? { headers: extraHeaders } : {}
|
|
8321
8416
|
};
|
|
8322
8417
|
return new OpenAiCompatEngine({ fetch: opts.fetch, grant }, { ...OLLAMA_COMPAT_IDENTITY, providerLabel: compat.label });
|
|
8323
8418
|
}
|
|
@@ -8326,6 +8421,7 @@ function makeProvider(name, _model, opts) {
|
|
|
8326
8421
|
var OLLAMA_COMPAT_IDENTITY;
|
|
8327
8422
|
var init_make_provider = __esm(() => {
|
|
8328
8423
|
init_providers();
|
|
8424
|
+
init_catalog();
|
|
8329
8425
|
init_anthropic_provider();
|
|
8330
8426
|
init_openai_compat_provider();
|
|
8331
8427
|
init_fake_provider();
|
|
@@ -40876,78 +40972,6 @@ async function startStdioTransport(server) {
|
|
|
40876
40972
|
await server.connect(transport);
|
|
40877
40973
|
}
|
|
40878
40974
|
|
|
40879
|
-
// src/lib/oauth/catalog.ts
|
|
40880
|
-
function authCatalogEntry(provider) {
|
|
40881
|
-
return PROVIDER_AUTH_CATALOG.find((entry) => entry.provider === provider);
|
|
40882
|
-
}
|
|
40883
|
-
function catalogMethods(provider) {
|
|
40884
|
-
return authCatalogEntry(provider)?.methods ?? ["api-key"];
|
|
40885
|
-
}
|
|
40886
|
-
function catalogAllows(provider, method) {
|
|
40887
|
-
return catalogMethods(provider).includes(method);
|
|
40888
|
-
}
|
|
40889
|
-
function catalogRefusal(provider) {
|
|
40890
|
-
return authCatalogEntry(provider)?.refusal;
|
|
40891
|
-
}
|
|
40892
|
-
function deviceCodeMethodLabel(provider) {
|
|
40893
|
-
if (provider === "grok")
|
|
40894
|
-
return "SuperGrok Subscription";
|
|
40895
|
-
if (provider === "github-copilot")
|
|
40896
|
-
return "Login with GitHub Copilot";
|
|
40897
|
-
if (provider === "openai")
|
|
40898
|
-
return "ChatGPT Plus/Pro (headless)";
|
|
40899
|
-
return "Device authorization";
|
|
40900
|
-
}
|
|
40901
|
-
var XAI_GROK_DEVICE, GITHUB_COPILOT_DEVICE, PROVIDER_AUTH_CATALOG;
|
|
40902
|
-
var init_catalog = __esm(() => {
|
|
40903
|
-
XAI_GROK_DEVICE = {
|
|
40904
|
-
deviceAuthorizationEndpoint: "https://auth.x.ai/oauth2/device/code",
|
|
40905
|
-
tokenEndpoint: "https://auth.x.ai/oauth2/token",
|
|
40906
|
-
clientId: "b1a00492-073a-47ea-816f-4c329264a828",
|
|
40907
|
-
scope: "openid profile email offline_access grok-cli:access api:access",
|
|
40908
|
-
extraForm: { referrer: "keryx" },
|
|
40909
|
-
headers: { "User-Agent": "keryx" }
|
|
40910
|
-
};
|
|
40911
|
-
GITHUB_COPILOT_DEVICE = {
|
|
40912
|
-
deviceAuthorizationEndpoint: "https://github.com/login/device/code",
|
|
40913
|
-
tokenEndpoint: "https://github.com/login/oauth/access_token",
|
|
40914
|
-
clientId: "Ov23li8tweQw6odWQebz",
|
|
40915
|
-
scope: "read:user",
|
|
40916
|
-
headers: { Accept: "application/json", "User-Agent": "keryx" },
|
|
40917
|
-
afterToken: "github-copilot"
|
|
40918
|
-
};
|
|
40919
|
-
PROVIDER_AUTH_CATALOG = [
|
|
40920
|
-
{
|
|
40921
|
-
provider: "grok",
|
|
40922
|
-
label: "xAI (Grok)",
|
|
40923
|
-
methods: ["device-code", "api-key"],
|
|
40924
|
-
device: XAI_GROK_DEVICE
|
|
40925
|
-
},
|
|
40926
|
-
{
|
|
40927
|
-
provider: "openai",
|
|
40928
|
-
label: "OpenAI",
|
|
40929
|
-
methods: ["oauth-pkce-loopback", "device-code", "api-key"]
|
|
40930
|
-
},
|
|
40931
|
-
{
|
|
40932
|
-
provider: "github-copilot",
|
|
40933
|
-
label: "GitHub Copilot",
|
|
40934
|
-
methods: ["device-code"],
|
|
40935
|
-
device: GITHUB_COPILOT_DEVICE
|
|
40936
|
-
},
|
|
40937
|
-
{ provider: "anthropic", label: "Anthropic", methods: ["api-key"], refusal: "Anthropic does not permit third-party Claude Pro/Max login. Use an API key from the Anthropic Console." },
|
|
40938
|
-
{ provider: "gemini", label: "Google Gemini", methods: ["api-key"], refusal: "Gemini Google-account login is for Gemini CLI. In keryx use GEMINI_API_KEY from Google AI Studio." },
|
|
40939
|
-
{ provider: "deepseek", label: "DeepSeek", methods: ["api-key"], refusal: "DeepSeek has no consumer OAuth grant. Use DEEPSEEK_API_KEY." },
|
|
40940
|
-
{ provider: "openrouter", label: "OpenRouter", methods: ["api-key"] },
|
|
40941
|
-
{ provider: "zai", label: "Z.AI (GLM)", methods: ["api-key"] },
|
|
40942
|
-
{ provider: "zai-coding", label: "Z.AI GLM Coding Plan", methods: ["api-key"] },
|
|
40943
|
-
{ provider: "cerebras", label: "Cerebras", methods: ["api-key"] },
|
|
40944
|
-
{ provider: "groq", label: "Groq", methods: ["api-key"] },
|
|
40945
|
-
{ provider: "moonshot", label: "Moonshot (Kimi)", methods: ["api-key"] },
|
|
40946
|
-
{ provider: "ollama", label: "Ollama", methods: ["none"] },
|
|
40947
|
-
{ provider: "rapid-mlx", label: "Rapid-MLX (Local)", methods: ["none"] }
|
|
40948
|
-
];
|
|
40949
|
-
});
|
|
40950
|
-
|
|
40951
40975
|
// src/lib/oauth/device-code.ts
|
|
40952
40976
|
function requestInit(base, signal) {
|
|
40953
40977
|
return signal === undefined ? base : { ...base, signal };
|
|
@@ -41115,38 +41139,94 @@ var init_device_code = __esm(() => {
|
|
|
41115
41139
|
});
|
|
41116
41140
|
|
|
41117
41141
|
// src/lib/oauth/copilot.ts
|
|
41142
|
+
function copilotApiBaseFromExchange(raw) {
|
|
41143
|
+
if (typeof raw !== "string" || raw.length === 0) {
|
|
41144
|
+
return;
|
|
41145
|
+
}
|
|
41146
|
+
try {
|
|
41147
|
+
const url = new URL(raw);
|
|
41148
|
+
if (url.protocol !== "https:" || url.username.length > 0 || url.password.length > 0) {
|
|
41149
|
+
return;
|
|
41150
|
+
}
|
|
41151
|
+
const host = url.hostname;
|
|
41152
|
+
if (host !== "api.githubcopilot.com" && !host.endsWith(".githubcopilot.com")) {
|
|
41153
|
+
return;
|
|
41154
|
+
}
|
|
41155
|
+
return `https://${host}${url.port.length > 0 ? `:${url.port}` : ""}`;
|
|
41156
|
+
} catch {
|
|
41157
|
+
return;
|
|
41158
|
+
}
|
|
41159
|
+
}
|
|
41160
|
+
function expiresInSecondsFrom(rec, now) {
|
|
41161
|
+
if (typeof rec.expires_at === "string") {
|
|
41162
|
+
const expires = Date.parse(rec.expires_at);
|
|
41163
|
+
if (Number.isFinite(expires)) {
|
|
41164
|
+
return Math.max(1, Math.floor((expires - now) / 1000));
|
|
41165
|
+
}
|
|
41166
|
+
}
|
|
41167
|
+
if (typeof rec.expires_at === "number" && Number.isFinite(rec.expires_at)) {
|
|
41168
|
+
const expiresMs = rec.expires_at < 1000000000000 ? rec.expires_at * 1000 : rec.expires_at;
|
|
41169
|
+
return Math.max(1, Math.floor((expiresMs - now) / 1000));
|
|
41170
|
+
}
|
|
41171
|
+
if (typeof rec.refresh_in === "number" && Number.isFinite(rec.refresh_in) && rec.refresh_in > 0) {
|
|
41172
|
+
return Math.floor(rec.refresh_in);
|
|
41173
|
+
}
|
|
41174
|
+
return;
|
|
41175
|
+
}
|
|
41176
|
+
function describeExchangeFailure(status, json, body) {
|
|
41177
|
+
if (typeof json === "object" && json !== null) {
|
|
41178
|
+
const rec = json;
|
|
41179
|
+
if (rec.error_details?.copilot_access_denied === true) {
|
|
41180
|
+
return `GitHub Copilot token exchange failed (HTTP ${status}): Copilot access denied \u2014 check the GitHub Copilot subscription on this account`;
|
|
41181
|
+
}
|
|
41182
|
+
if (typeof rec.message === "string" && rec.message.length > 0) {
|
|
41183
|
+
return `GitHub Copilot token exchange failed (HTTP ${status}): ${rec.message}`;
|
|
41184
|
+
}
|
|
41185
|
+
}
|
|
41186
|
+
if (/zscaler|blocked because it does not comply/i.test(body)) {
|
|
41187
|
+
return `GitHub Copilot token exchange failed (HTTP ${status}): request was blocked by a gateway or proxy`;
|
|
41188
|
+
}
|
|
41189
|
+
return `GitHub Copilot token exchange failed (HTTP ${status})`;
|
|
41190
|
+
}
|
|
41118
41191
|
async function exchangeGithubTokenForCopilot(githubToken, http) {
|
|
41119
41192
|
const init = {
|
|
41120
41193
|
method: "GET",
|
|
41121
41194
|
headers: {
|
|
41122
|
-
|
|
41123
|
-
|
|
41124
|
-
"User-Agent": "keryx"
|
|
41195
|
+
...GITHUB_COPILOT_REQUEST_HEADERS,
|
|
41196
|
+
Authorization: `token ${githubToken}`
|
|
41125
41197
|
}
|
|
41126
41198
|
};
|
|
41127
41199
|
if (http.signal !== undefined) {
|
|
41128
41200
|
init.signal = http.signal;
|
|
41129
41201
|
}
|
|
41130
41202
|
const response = await http.fetch(COPILOT_TOKEN_URL, init);
|
|
41131
|
-
const
|
|
41203
|
+
const body = await response.text().catch(() => "");
|
|
41204
|
+
let json = {};
|
|
41205
|
+
if (body.length > 0) {
|
|
41206
|
+
try {
|
|
41207
|
+
json = JSON.parse(body);
|
|
41208
|
+
} catch {
|
|
41209
|
+
json = {};
|
|
41210
|
+
}
|
|
41211
|
+
}
|
|
41132
41212
|
if (!response.ok || typeof json !== "object" || json === null) {
|
|
41133
|
-
throw new DeviceCodeError("failed",
|
|
41213
|
+
throw new DeviceCodeError("failed", describeExchangeFailure(response.status, json, body));
|
|
41134
41214
|
}
|
|
41135
41215
|
const rec = json;
|
|
41136
41216
|
if (typeof rec.token !== "string" || rec.token.length === 0) {
|
|
41137
41217
|
throw new DeviceCodeError("failed", "GitHub Copilot token exchange returned no token");
|
|
41138
41218
|
}
|
|
41139
|
-
|
|
41140
|
-
|
|
41141
|
-
|
|
41142
|
-
|
|
41143
|
-
|
|
41144
|
-
}
|
|
41145
|
-
}
|
|
41146
|
-
return { accessToken: rec.token, ...expiresInSeconds !== undefined ? { expiresInSeconds } : {} };
|
|
41219
|
+
const expiresInSeconds = expiresInSecondsFrom(rec, Date.now());
|
|
41220
|
+
const apiBaseUrl = copilotApiBaseFromExchange(rec.endpoints?.api);
|
|
41221
|
+
return {
|
|
41222
|
+
accessToken: rec.token,
|
|
41223
|
+
...expiresInSeconds !== undefined ? { expiresInSeconds } : {},
|
|
41224
|
+
...apiBaseUrl !== undefined ? { apiBaseUrl } : {}
|
|
41225
|
+
};
|
|
41147
41226
|
}
|
|
41148
41227
|
var COPILOT_TOKEN_URL = "https://api.github.com/copilot_internal/v2/token";
|
|
41149
41228
|
var init_copilot = __esm(() => {
|
|
41229
|
+
init_catalog();
|
|
41150
41230
|
init_device_code();
|
|
41151
41231
|
});
|
|
41152
41232
|
|
|
@@ -41266,6 +41346,9 @@ async function loginRfc8628(input) {
|
|
|
41266
41346
|
}, http);
|
|
41267
41347
|
if (endpoints.afterToken === "github-copilot") {
|
|
41268
41348
|
const copilot = await exchangeGithubTokenForCopilot(tokens.accessToken, http);
|
|
41349
|
+
if (copilot.apiBaseUrl !== undefined) {
|
|
41350
|
+
saveProviderBaseUrl("github-copilot", copilot.apiBaseUrl, input.dir);
|
|
41351
|
+
}
|
|
41269
41352
|
return {
|
|
41270
41353
|
accessToken: copilot.accessToken,
|
|
41271
41354
|
refreshToken: tokens.accessToken,
|
|
@@ -41315,6 +41398,9 @@ async function refreshProviderGrant(provider, http, dir) {
|
|
|
41315
41398
|
const endpoints = provider === "github-copilot" ? GITHUB_COPILOT_DEVICE : XAI_GROK_DEVICE;
|
|
41316
41399
|
if (provider === "github-copilot") {
|
|
41317
41400
|
const copilot = await exchangeGithubTokenForCopilot(grant.refresh, http);
|
|
41401
|
+
if (copilot.apiBaseUrl !== undefined) {
|
|
41402
|
+
saveProviderBaseUrl("github-copilot", copilot.apiBaseUrl, dir);
|
|
41403
|
+
}
|
|
41318
41404
|
const next = grantFromTokens("device-code", {
|
|
41319
41405
|
accessToken: copilot.accessToken,
|
|
41320
41406
|
refreshToken: grant.refresh,
|
|
@@ -41369,6 +41455,7 @@ function logoutProvider(provider, dir) {
|
|
|
41369
41455
|
}
|
|
41370
41456
|
var SESSION_REFRESHED_GRANTS;
|
|
41371
41457
|
var init_login = __esm(() => {
|
|
41458
|
+
init_shell_config();
|
|
41372
41459
|
init_catalog();
|
|
41373
41460
|
init_copilot();
|
|
41374
41461
|
init_device_code();
|
|
@@ -48173,7 +48260,7 @@ import path47 from "path";
|
|
|
48173
48260
|
// package.json
|
|
48174
48261
|
var package_default = {
|
|
48175
48262
|
name: "@mrciphersmith/keryx",
|
|
48176
|
-
version: "0.2.
|
|
48263
|
+
version: "0.2.102",
|
|
48177
48264
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
48178
48265
|
private: false,
|
|
48179
48266
|
publishConfig: {
|
|
@@ -94966,7 +95053,7 @@ function pickAuthMethodStep(otui, r, providerLabel, methods) {
|
|
|
94966
95053
|
});
|
|
94967
95054
|
});
|
|
94968
95055
|
}
|
|
94969
|
-
function runDeviceLoginInTui(otui, r, provider) {
|
|
95056
|
+
function runDeviceLoginInTui(otui, r, provider, dir) {
|
|
94970
95057
|
return new Promise((resolve) => {
|
|
94971
95058
|
const box = overlayBox(otui, r, "device-login");
|
|
94972
95059
|
r.root.add(box);
|
|
@@ -94994,6 +95081,7 @@ function runDeviceLoginInTui(otui, r, provider) {
|
|
|
94994
95081
|
provider,
|
|
94995
95082
|
fetch: (input, init) => globalThis.fetch(input, init),
|
|
94996
95083
|
signal: controller.signal,
|
|
95084
|
+
...dir !== undefined ? { dir } : {},
|
|
94997
95085
|
onChallenge: (challenge) => {
|
|
94998
95086
|
status.content = otui.t`${otui.bold(challenge.userCode)}\n${otui.dim(challenge.verificationUri)}\n${otui.dim("Open that URL on any device and enter the code. Waiting for authorization\u2026")}`;
|
|
94999
95087
|
openVerificationUrl(challenge.verificationUriComplete ?? challenge.verificationUri);
|
|
@@ -95110,12 +95198,14 @@ function selectProviderModelInTui(otui, r, detected, options = {}) {
|
|
|
95110
95198
|
}
|
|
95111
95199
|
continue;
|
|
95112
95200
|
}
|
|
95113
|
-
|
|
95114
|
-
|
|
95201
|
+
const lockDiscoveredHost = prov.name === "github-copilot";
|
|
95202
|
+
let selectedBaseUrl = options.onlyConnected || prov.baseUrl === undefined || lockDiscoveredHost ? prov.baseUrl : await promptBaseUrlStep(otui, r, prov.label ?? prov.name, prov.baseUrl);
|
|
95203
|
+
if (!options.onlyConnected && !lockDiscoveredHost && prov.baseUrl !== undefined && selectedBaseUrl === undefined) {
|
|
95115
95204
|
continue;
|
|
95116
95205
|
}
|
|
95117
|
-
if (!options.onlyConnected && selectedBaseUrl !== undefined)
|
|
95206
|
+
if (!options.onlyConnected && !lockDiscoveredHost && selectedBaseUrl !== undefined) {
|
|
95118
95207
|
saveProviderBaseUrl(prov.name, selectedBaseUrl, options.configDir);
|
|
95208
|
+
}
|
|
95119
95209
|
let selectedProvider = selectedBaseUrl === undefined ? prov : { ...prov, baseUrl: selectedBaseUrl };
|
|
95120
95210
|
const envKey = prov.envKey;
|
|
95121
95211
|
const label = prov.label ?? prov.name;
|
|
@@ -95143,7 +95233,15 @@ function selectProviderModelInTui(otui, r, detected, options = {}) {
|
|
|
95143
95233
|
}
|
|
95144
95234
|
}
|
|
95145
95235
|
if (method === "device-code") {
|
|
95146
|
-
|
|
95236
|
+
if (!await runDeviceLoginInTui(otui, r, prov.name, options.configDir)) {
|
|
95237
|
+
return "back";
|
|
95238
|
+
}
|
|
95239
|
+
const saved = loadShellConfig(options.configDir).baseUrls?.[prov.name];
|
|
95240
|
+
if (typeof saved === "string" && saved.length > 0) {
|
|
95241
|
+
selectedBaseUrl = saved;
|
|
95242
|
+
selectedProvider = { ...prov, baseUrl: saved };
|
|
95243
|
+
}
|
|
95244
|
+
return "ok";
|
|
95147
95245
|
}
|
|
95148
95246
|
const kr = await promptApiKeyStep(otui, r, {
|
|
95149
95247
|
label,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.102",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|