claudish 6.10.1 → 6.11.1
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/index.js +625 -514
- package/package.json +5 -5
- package/recommended-models.json +2 -2
package/dist/index.js
CHANGED
|
@@ -16928,6 +16928,45 @@ var init_logger = __esm(() => {
|
|
|
16928
16928
|
]);
|
|
16929
16929
|
});
|
|
16930
16930
|
|
|
16931
|
+
// src/handlers/shared/anthropic-error.ts
|
|
16932
|
+
function statusToErrorType(status) {
|
|
16933
|
+
switch (status) {
|
|
16934
|
+
case 400:
|
|
16935
|
+
return "invalid_request_error";
|
|
16936
|
+
case 401:
|
|
16937
|
+
return "authentication_error";
|
|
16938
|
+
case 403:
|
|
16939
|
+
return "permission_error";
|
|
16940
|
+
case 404:
|
|
16941
|
+
return "not_found_error";
|
|
16942
|
+
case 429:
|
|
16943
|
+
return "rate_limit_error";
|
|
16944
|
+
case 503:
|
|
16945
|
+
case 529:
|
|
16946
|
+
return "overloaded_error";
|
|
16947
|
+
default:
|
|
16948
|
+
return "api_error";
|
|
16949
|
+
}
|
|
16950
|
+
}
|
|
16951
|
+
function wrapAnthropicError(status, message, errorType) {
|
|
16952
|
+
const type = errorType || statusToErrorType(status);
|
|
16953
|
+
return {
|
|
16954
|
+
type: "error",
|
|
16955
|
+
error: { type, message }
|
|
16956
|
+
};
|
|
16957
|
+
}
|
|
16958
|
+
function ensureAnthropicErrorFormat(status, body) {
|
|
16959
|
+
if (body?.type === "error" && typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
|
|
16960
|
+
return body;
|
|
16961
|
+
}
|
|
16962
|
+
if (typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
|
|
16963
|
+
return { type: "error", error: body.error };
|
|
16964
|
+
}
|
|
16965
|
+
const message = body?.error?.message || body?.message || body?.error || (typeof body === "string" ? body : JSON.stringify(body));
|
|
16966
|
+
const errorType = body?.error?.type || body?.type || body?.code;
|
|
16967
|
+
return wrapAnthropicError(status, String(message), errorType);
|
|
16968
|
+
}
|
|
16969
|
+
|
|
16931
16970
|
// src/handlers/native-handler.ts
|
|
16932
16971
|
class NativeHandler {
|
|
16933
16972
|
apiKey;
|
|
@@ -17019,7 +17058,7 @@ class NativeHandler {
|
|
|
17019
17058
|
return c.json(data, { status: anthropicResponse.status, headers: responseHeaders });
|
|
17020
17059
|
} catch (error2) {
|
|
17021
17060
|
log(`[Native] Fetch Error: ${error2}`);
|
|
17022
|
-
return c.json(
|
|
17061
|
+
return c.json(wrapAnthropicError(500, String(error2)), 500);
|
|
17023
17062
|
}
|
|
17024
17063
|
}
|
|
17025
17064
|
async shutdown() {}
|
|
@@ -17285,6 +17324,24 @@ function loadRecommendedModelsJSON() {
|
|
|
17285
17324
|
if (_cachedRecommendedModels) {
|
|
17286
17325
|
return _cachedRecommendedModels;
|
|
17287
17326
|
}
|
|
17327
|
+
if (existsSync3(RECOMMENDED_CACHE_PATH)) {
|
|
17328
|
+
try {
|
|
17329
|
+
const cacheData = JSON.parse(readFileSync2(RECOMMENDED_CACHE_PATH, "utf-8"));
|
|
17330
|
+
if (cacheData.models && cacheData.models.length > 0) {
|
|
17331
|
+
const generatedAt = cacheData.generatedAt;
|
|
17332
|
+
if (generatedAt) {
|
|
17333
|
+
const ageHours = (Date.now() - new Date(generatedAt).getTime()) / (1000 * 60 * 60);
|
|
17334
|
+
if (ageHours <= RECOMMENDED_CACHE_MAX_AGE_HOURS) {
|
|
17335
|
+
_cachedRecommendedModels = cacheData;
|
|
17336
|
+
return cacheData;
|
|
17337
|
+
}
|
|
17338
|
+
} else {
|
|
17339
|
+
_cachedRecommendedModels = cacheData;
|
|
17340
|
+
return cacheData;
|
|
17341
|
+
}
|
|
17342
|
+
}
|
|
17343
|
+
} catch {}
|
|
17344
|
+
}
|
|
17288
17345
|
const jsonPath = getRecommendedModelsPath();
|
|
17289
17346
|
if (!existsSync3(jsonPath)) {
|
|
17290
17347
|
throw new Error(`recommended-models.json not found at ${jsonPath}. ` + `Run 'claudish --update-models' to fetch the latest model list.`);
|
|
@@ -17429,10 +17486,11 @@ async function fetchLiteLLMModels(baseUrl, apiKey, forceUpdate = false) {
|
|
|
17429
17486
|
return [];
|
|
17430
17487
|
}
|
|
17431
17488
|
}
|
|
17432
|
-
var __filename2, __dirname2, _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels = null, _cachedOpenRouterModels = null, LITELLM_CACHE_MAX_AGE_HOURS = 24;
|
|
17489
|
+
var __filename2, __dirname2, _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels = null, RECOMMENDED_CACHE_PATH, RECOMMENDED_CACHE_MAX_AGE_HOURS = 12, _cachedOpenRouterModels = null, LITELLM_CACHE_MAX_AGE_HOURS = 24;
|
|
17433
17490
|
var init_model_loader = __esm(() => {
|
|
17434
17491
|
__filename2 = fileURLToPath(import.meta.url);
|
|
17435
17492
|
__dirname2 = dirname(__filename2);
|
|
17493
|
+
RECOMMENDED_CACHE_PATH = join4(homedir3(), ".claudish", "recommended-models-cache.json");
|
|
17436
17494
|
});
|
|
17437
17495
|
|
|
17438
17496
|
// src/providers/transport/openrouter.ts
|
|
@@ -17467,7 +17525,7 @@ class OpenRouterProviderTransport {
|
|
|
17467
17525
|
getContextWindow() {
|
|
17468
17526
|
const models = this.modelId ? getCachedOpenRouterModels() : null;
|
|
17469
17527
|
const model = models?.find((m) => m.id === this.modelId);
|
|
17470
|
-
return model?.context_length || model?.top_provider?.context_length ||
|
|
17528
|
+
return model?.context_length || model?.top_provider?.context_length || 0;
|
|
17471
17529
|
}
|
|
17472
17530
|
}
|
|
17473
17531
|
var OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions";
|
|
@@ -17550,6 +17608,83 @@ var init_remote_provider_types = __esm(() => {
|
|
|
17550
17608
|
};
|
|
17551
17609
|
});
|
|
17552
17610
|
|
|
17611
|
+
// src/adapters/model-catalog.ts
|
|
17612
|
+
function lookupModel(modelId) {
|
|
17613
|
+
const lower = modelId.toLowerCase();
|
|
17614
|
+
let unprefixed = lower;
|
|
17615
|
+
if (lower.includes("@"))
|
|
17616
|
+
unprefixed = lower.substring(lower.indexOf("@") + 1);
|
|
17617
|
+
else if (lower.includes("/"))
|
|
17618
|
+
unprefixed = lower.substring(lower.lastIndexOf("/") + 1);
|
|
17619
|
+
for (const entry of MODEL_CATALOG) {
|
|
17620
|
+
if (unprefixed.includes(entry.pattern) || lower.includes(entry.pattern)) {
|
|
17621
|
+
return entry;
|
|
17622
|
+
}
|
|
17623
|
+
}
|
|
17624
|
+
return;
|
|
17625
|
+
}
|
|
17626
|
+
var MODEL_CATALOG;
|
|
17627
|
+
var init_model_catalog = __esm(() => {
|
|
17628
|
+
MODEL_CATALOG = [
|
|
17629
|
+
{ pattern: "grok-4.20", contextWindow: 2000000 },
|
|
17630
|
+
{ pattern: "grok-4-20", contextWindow: 2000000 },
|
|
17631
|
+
{ pattern: "grok-4.1-fast", contextWindow: 2000000 },
|
|
17632
|
+
{ pattern: "grok-4-1-fast", contextWindow: 2000000 },
|
|
17633
|
+
{ pattern: "grok-4-fast", contextWindow: 2000000 },
|
|
17634
|
+
{ pattern: "grok-code-fast", contextWindow: 256000 },
|
|
17635
|
+
{ pattern: "grok-4", contextWindow: 256000 },
|
|
17636
|
+
{ pattern: "grok-3", contextWindow: 131072 },
|
|
17637
|
+
{ pattern: "grok-2", contextWindow: 131072 },
|
|
17638
|
+
{ pattern: "glm-5-turbo", contextWindow: 202752 },
|
|
17639
|
+
{ pattern: "glm-5", contextWindow: 80000, supportsVision: true },
|
|
17640
|
+
{ pattern: "glm-4.7-flash", contextWindow: 202752 },
|
|
17641
|
+
{ pattern: "glm-4.7", contextWindow: 202752 },
|
|
17642
|
+
{ pattern: "glm-4.6v", contextWindow: 131072, supportsVision: true },
|
|
17643
|
+
{ pattern: "glm-4.6", contextWindow: 204800 },
|
|
17644
|
+
{ pattern: "glm-4.5v", contextWindow: 65536, supportsVision: true },
|
|
17645
|
+
{ pattern: "glm-4.5-flash", contextWindow: 131072 },
|
|
17646
|
+
{ pattern: "glm-4.5-air", contextWindow: 131072 },
|
|
17647
|
+
{ pattern: "glm-4.5", contextWindow: 131072 },
|
|
17648
|
+
{ pattern: "glm-4v-plus", contextWindow: 128000, supportsVision: true },
|
|
17649
|
+
{ pattern: "glm-4v", contextWindow: 128000, supportsVision: true },
|
|
17650
|
+
{ pattern: "glm-4-long", contextWindow: 1e6 },
|
|
17651
|
+
{ pattern: "glm-4-plus", contextWindow: 128000 },
|
|
17652
|
+
{ pattern: "glm-4-flash", contextWindow: 128000 },
|
|
17653
|
+
{ pattern: "glm-4-32b", contextWindow: 128000 },
|
|
17654
|
+
{ pattern: "glm-4", contextWindow: 128000 },
|
|
17655
|
+
{ pattern: "glm-3-turbo", contextWindow: 128000 },
|
|
17656
|
+
{ pattern: "minimax-01", contextWindow: 1e6, supportsVision: false },
|
|
17657
|
+
{ pattern: "minimax-m1", contextWindow: 1e6, supportsVision: false },
|
|
17658
|
+
{
|
|
17659
|
+
pattern: "minimax",
|
|
17660
|
+
contextWindow: 0,
|
|
17661
|
+
supportsVision: false,
|
|
17662
|
+
temperatureRange: { min: 0.01, max: 1 }
|
|
17663
|
+
},
|
|
17664
|
+
{ pattern: "gpt-5.4", contextWindow: 1050000, maxToolCount: 128 },
|
|
17665
|
+
{ pattern: "gpt-5", contextWindow: 400000, maxToolCount: 128 },
|
|
17666
|
+
{ pattern: "o1", contextWindow: 200000, maxToolCount: 128 },
|
|
17667
|
+
{ pattern: "o3", contextWindow: 200000, maxToolCount: 128 },
|
|
17668
|
+
{ pattern: "o4", contextWindow: 200000, maxToolCount: 128 },
|
|
17669
|
+
{ pattern: "gpt-4o", contextWindow: 128000, maxToolCount: 128 },
|
|
17670
|
+
{ pattern: "gpt-4-turbo", contextWindow: 128000, maxToolCount: 128 },
|
|
17671
|
+
{ pattern: "gpt-3.5", contextWindow: 16385, maxToolCount: 128 },
|
|
17672
|
+
{ pattern: "kimi-k2.5", contextWindow: 262144 },
|
|
17673
|
+
{ pattern: "kimi-k2-5", contextWindow: 262144 },
|
|
17674
|
+
{ pattern: "kimi-k2", contextWindow: 131000 },
|
|
17675
|
+
{ pattern: "qwen3.6", contextWindow: 1048576 },
|
|
17676
|
+
{ pattern: "qwen3-6", contextWindow: 1048576 },
|
|
17677
|
+
{ pattern: "qwen3.5", contextWindow: 262144 },
|
|
17678
|
+
{ pattern: "qwen3-5", contextWindow: 262144 },
|
|
17679
|
+
{ pattern: "qwen3-coder", contextWindow: 262144 },
|
|
17680
|
+
{ pattern: "qwen3", contextWindow: 131072 },
|
|
17681
|
+
{ pattern: "qwen2.5", contextWindow: 131072 },
|
|
17682
|
+
{ pattern: "qwen2-5", contextWindow: 131072 },
|
|
17683
|
+
{ pattern: "xiaomi", contextWindow: 0, toolNameLimit: 64 },
|
|
17684
|
+
{ pattern: "mimo", contextWindow: 0, toolNameLimit: 64 }
|
|
17685
|
+
];
|
|
17686
|
+
});
|
|
17687
|
+
|
|
17553
17688
|
// src/handlers/shared/format/openai-messages.ts
|
|
17554
17689
|
function convertMessagesToOpenAI(req, modelId, filterIdentityFn, simpleFormat = false) {
|
|
17555
17690
|
const messages = [];
|
|
@@ -17830,7 +17965,7 @@ var init_openai_tools = __esm(() => {
|
|
|
17830
17965
|
function matchesModelFamily(modelId, family) {
|
|
17831
17966
|
const lower = modelId.toLowerCase();
|
|
17832
17967
|
const fam = family.toLowerCase();
|
|
17833
|
-
return lower.startsWith(fam) || lower.includes(`/${fam}`);
|
|
17968
|
+
return lower.startsWith(fam) || lower.includes(`/${fam}`) || lower.includes(`@${fam}`);
|
|
17834
17969
|
}
|
|
17835
17970
|
|
|
17836
17971
|
class BaseAPIFormat {
|
|
@@ -17881,7 +18016,7 @@ class BaseAPIFormat {
|
|
|
17881
18016
|
return "openai-sse";
|
|
17882
18017
|
}
|
|
17883
18018
|
getContextWindow() {
|
|
17884
|
-
return
|
|
18019
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
17885
18020
|
}
|
|
17886
18021
|
getPricing(providerName) {
|
|
17887
18022
|
return getModelPricing(providerName, this.modelId);
|
|
@@ -17930,6 +18065,7 @@ var DefaultAPIFormat;
|
|
|
17930
18065
|
var init_base_api_format = __esm(() => {
|
|
17931
18066
|
init_tool_name_utils();
|
|
17932
18067
|
init_remote_provider_types();
|
|
18068
|
+
init_model_catalog();
|
|
17933
18069
|
init_openai_tools();
|
|
17934
18070
|
DefaultAPIFormat = class DefaultAPIFormat extends BaseAPIFormat {
|
|
17935
18071
|
processTextContent(textContent, accumulatedText) {
|
|
@@ -17948,74 +18084,6 @@ var init_base_api_format = __esm(() => {
|
|
|
17948
18084
|
};
|
|
17949
18085
|
});
|
|
17950
18086
|
|
|
17951
|
-
// src/adapters/model-catalog.ts
|
|
17952
|
-
function lookupModel(modelId) {
|
|
17953
|
-
const lower = modelId.toLowerCase();
|
|
17954
|
-
const unprefixed = lower.includes("/") ? lower.substring(lower.lastIndexOf("/") + 1) : lower;
|
|
17955
|
-
for (const entry of MODEL_CATALOG) {
|
|
17956
|
-
if (unprefixed.includes(entry.pattern) || lower.includes(entry.pattern)) {
|
|
17957
|
-
return entry;
|
|
17958
|
-
}
|
|
17959
|
-
}
|
|
17960
|
-
return;
|
|
17961
|
-
}
|
|
17962
|
-
var MODEL_CATALOG;
|
|
17963
|
-
var init_model_catalog = __esm(() => {
|
|
17964
|
-
MODEL_CATALOG = [
|
|
17965
|
-
{ pattern: "grok-4.20", contextWindow: 2000000 },
|
|
17966
|
-
{ pattern: "grok-4-20", contextWindow: 2000000 },
|
|
17967
|
-
{ pattern: "grok-4.1-fast", contextWindow: 2000000 },
|
|
17968
|
-
{ pattern: "grok-4-1-fast", contextWindow: 2000000 },
|
|
17969
|
-
{ pattern: "grok-4-fast", contextWindow: 2000000 },
|
|
17970
|
-
{ pattern: "grok-code-fast", contextWindow: 256000 },
|
|
17971
|
-
{ pattern: "grok-4", contextWindow: 256000 },
|
|
17972
|
-
{ pattern: "grok-3", contextWindow: 131072 },
|
|
17973
|
-
{ pattern: "grok-2", contextWindow: 131072 },
|
|
17974
|
-
{ pattern: "grok", contextWindow: 131072 },
|
|
17975
|
-
{ pattern: "glm-5-turbo", contextWindow: 202752 },
|
|
17976
|
-
{ pattern: "glm-5", contextWindow: 80000, supportsVision: true },
|
|
17977
|
-
{ pattern: "glm-4.7-flash", contextWindow: 202752 },
|
|
17978
|
-
{ pattern: "glm-4.7", contextWindow: 202752 },
|
|
17979
|
-
{ pattern: "glm-4.6v", contextWindow: 131072, supportsVision: true },
|
|
17980
|
-
{ pattern: "glm-4.6", contextWindow: 204800 },
|
|
17981
|
-
{ pattern: "glm-4.5v", contextWindow: 65536, supportsVision: true },
|
|
17982
|
-
{ pattern: "glm-4.5-flash", contextWindow: 131072 },
|
|
17983
|
-
{ pattern: "glm-4.5-air", contextWindow: 131072 },
|
|
17984
|
-
{ pattern: "glm-4.5", contextWindow: 131072 },
|
|
17985
|
-
{ pattern: "glm-4v-plus", contextWindow: 128000, supportsVision: true },
|
|
17986
|
-
{ pattern: "glm-4v", contextWindow: 128000, supportsVision: true },
|
|
17987
|
-
{ pattern: "glm-4-long", contextWindow: 1e6 },
|
|
17988
|
-
{ pattern: "glm-4-plus", contextWindow: 128000 },
|
|
17989
|
-
{ pattern: "glm-4-flash", contextWindow: 128000 },
|
|
17990
|
-
{ pattern: "glm-4-32b", contextWindow: 128000 },
|
|
17991
|
-
{ pattern: "glm-4", contextWindow: 128000 },
|
|
17992
|
-
{ pattern: "glm-3-turbo", contextWindow: 128000 },
|
|
17993
|
-
{ pattern: "glm-", contextWindow: 131072, supportsVision: false },
|
|
17994
|
-
{ pattern: "minimax-01", contextWindow: 1e6, supportsVision: false },
|
|
17995
|
-
{ pattern: "minimax-m1", contextWindow: 1e6, supportsVision: false },
|
|
17996
|
-
{
|
|
17997
|
-
pattern: "minimax",
|
|
17998
|
-
contextWindow: 204800,
|
|
17999
|
-
supportsVision: false,
|
|
18000
|
-
temperatureRange: { min: 0.01, max: 1 }
|
|
18001
|
-
},
|
|
18002
|
-
{ pattern: "gpt-5.4", contextWindow: 1050000, maxToolCount: 128 },
|
|
18003
|
-
{ pattern: "gpt-5", contextWindow: 400000, maxToolCount: 128 },
|
|
18004
|
-
{ pattern: "o1", contextWindow: 200000, maxToolCount: 128 },
|
|
18005
|
-
{ pattern: "o3", contextWindow: 200000, maxToolCount: 128 },
|
|
18006
|
-
{ pattern: "o4", contextWindow: 200000, maxToolCount: 128 },
|
|
18007
|
-
{ pattern: "gpt-4o", contextWindow: 128000, maxToolCount: 128 },
|
|
18008
|
-
{ pattern: "gpt-4-turbo", contextWindow: 128000, maxToolCount: 128 },
|
|
18009
|
-
{ pattern: "gpt-3.5", contextWindow: 16385, maxToolCount: 128 },
|
|
18010
|
-
{ pattern: "kimi-k2.5", contextWindow: 262144 },
|
|
18011
|
-
{ pattern: "kimi-k2-5", contextWindow: 262144 },
|
|
18012
|
-
{ pattern: "kimi-k2", contextWindow: 131000 },
|
|
18013
|
-
{ pattern: "kimi", contextWindow: 131072 },
|
|
18014
|
-
{ pattern: "xiaomi", contextWindow: 200000, toolNameLimit: 64 },
|
|
18015
|
-
{ pattern: "mimo", contextWindow: 200000, toolNameLimit: 64 }
|
|
18016
|
-
];
|
|
18017
|
-
});
|
|
18018
|
-
|
|
18019
18087
|
// src/adapters/grok-model-dialect.ts
|
|
18020
18088
|
var GrokModelDialect;
|
|
18021
18089
|
var init_grok_model_dialect = __esm(() => {
|
|
@@ -18103,7 +18171,7 @@ var init_grok_model_dialect = __esm(() => {
|
|
|
18103
18171
|
return "GrokModelDialect";
|
|
18104
18172
|
}
|
|
18105
18173
|
getContextWindow() {
|
|
18106
|
-
return lookupModel(this.modelId)?.contextWindow ??
|
|
18174
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
18107
18175
|
}
|
|
18108
18176
|
reset() {
|
|
18109
18177
|
this.xmlBuffer = "";
|
|
@@ -18583,6 +18651,24 @@ var init_tool_call_recovery = __esm(() => {
|
|
|
18583
18651
|
init_logger();
|
|
18584
18652
|
});
|
|
18585
18653
|
|
|
18654
|
+
// src/handlers/shared/web-search-detector.ts
|
|
18655
|
+
function isWebSearchToolCall(toolName) {
|
|
18656
|
+
return WEB_SEARCH_NAMES.has(toolName);
|
|
18657
|
+
}
|
|
18658
|
+
function warnWebSearchUnsupported(toolName, modelName) {
|
|
18659
|
+
log(`[WebSearch] Tool call '${toolName}' detected from model '${modelName}' \u2014 not yet supported`);
|
|
18660
|
+
logStderr(`Warning: Model requested web search ('${toolName}') but server-side web search is not yet implemented. ` + `The tool call will pass through to the client as-is.`);
|
|
18661
|
+
}
|
|
18662
|
+
var WEB_SEARCH_NAMES;
|
|
18663
|
+
var init_web_search_detector = __esm(() => {
|
|
18664
|
+
init_logger();
|
|
18665
|
+
WEB_SEARCH_NAMES = new Set([
|
|
18666
|
+
"web_search",
|
|
18667
|
+
"brave_web_search",
|
|
18668
|
+
"tavily_search"
|
|
18669
|
+
]);
|
|
18670
|
+
});
|
|
18671
|
+
|
|
18586
18672
|
// src/handlers/shared/stream-parsers/openai-sse.ts
|
|
18587
18673
|
function validateToolArguments(toolName, argsStr, toolSchemas, textContent) {
|
|
18588
18674
|
const result = validateAndRepairToolCall(toolName, argsStr, toolSchemas, textContent);
|
|
@@ -18913,6 +18999,9 @@ data: ${JSON.stringify(d)}
|
|
|
18913
18999
|
buffered: !!toolSchemas && toolSchemas.length > 0
|
|
18914
19000
|
};
|
|
18915
19001
|
state.tools.set(idx, t);
|
|
19002
|
+
if (isWebSearchToolCall(restoredName)) {
|
|
19003
|
+
warnWebSearchUnsupported(restoredName, target);
|
|
19004
|
+
}
|
|
18916
19005
|
}
|
|
18917
19006
|
if (!t.started && !t.buffered) {
|
|
18918
19007
|
send("content_block_start", {
|
|
@@ -19079,6 +19168,7 @@ function estimateTokens(text) {
|
|
|
19079
19168
|
var init_openai_sse = __esm(() => {
|
|
19080
19169
|
init_logger();
|
|
19081
19170
|
init_tool_call_recovery();
|
|
19171
|
+
init_web_search_detector();
|
|
19082
19172
|
});
|
|
19083
19173
|
|
|
19084
19174
|
// src/handlers/shared/openai-compat.ts
|
|
@@ -19407,6 +19497,7 @@ CRITICAL INSTRUCTION FOR OUTPUT FORMAT:
|
|
|
19407
19497
|
var CodexAPIFormat;
|
|
19408
19498
|
var init_codex_api_format = __esm(() => {
|
|
19409
19499
|
init_base_api_format();
|
|
19500
|
+
init_model_catalog();
|
|
19410
19501
|
CodexAPIFormat = class CodexAPIFormat extends BaseAPIFormat {
|
|
19411
19502
|
constructor(modelId) {
|
|
19412
19503
|
super(modelId);
|
|
@@ -19428,7 +19519,7 @@ var init_codex_api_format = __esm(() => {
|
|
|
19428
19519
|
return "openai-responses-sse";
|
|
19429
19520
|
}
|
|
19430
19521
|
getContextWindow() {
|
|
19431
|
-
return
|
|
19522
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
19432
19523
|
}
|
|
19433
19524
|
buildPayload(claudeRequest, messages, tools) {
|
|
19434
19525
|
const convertedMessages = this.convertMessagesToResponsesAPI(messages);
|
|
@@ -19583,7 +19674,7 @@ var init_openai_api_format = __esm(() => {
|
|
|
19583
19674
|
return "OpenAIAPIFormat";
|
|
19584
19675
|
}
|
|
19585
19676
|
getContextWindow() {
|
|
19586
|
-
return lookupModel(this.modelId)?.contextWindow ??
|
|
19677
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
19587
19678
|
}
|
|
19588
19679
|
buildPayload(claudeRequest, messages, tools) {
|
|
19589
19680
|
return this.buildChatCompletionsPayload(claudeRequest, messages, tools);
|
|
@@ -19720,7 +19811,7 @@ var init_minimax_model_dialect = __esm(() => {
|
|
|
19720
19811
|
return request;
|
|
19721
19812
|
}
|
|
19722
19813
|
getContextWindow() {
|
|
19723
|
-
return lookupModel(this.modelId)?.contextWindow ??
|
|
19814
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
19724
19815
|
}
|
|
19725
19816
|
supportsVision() {
|
|
19726
19817
|
return lookupModel(this.modelId)?.supportsVision ?? false;
|
|
@@ -19791,7 +19882,7 @@ var init_glm_model_dialect = __esm(() => {
|
|
|
19791
19882
|
return "GLMModelDialect";
|
|
19792
19883
|
}
|
|
19793
19884
|
getContextWindow() {
|
|
19794
|
-
return lookupModel(this.modelId)?.contextWindow ??
|
|
19885
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
19795
19886
|
}
|
|
19796
19887
|
supportsVision() {
|
|
19797
19888
|
return lookupModel(this.modelId)?.supportsVision ?? false;
|
|
@@ -20963,7 +21054,7 @@ class TokenTracker {
|
|
|
20963
21054
|
try {
|
|
20964
21055
|
const total = inputTokens + outputTokens;
|
|
20965
21056
|
const cw = this.config.contextWindow;
|
|
20966
|
-
const leftPct = cw > 0 ? Math.max(0, Math.min(100, Math.round((cw - total) / cw * 100))) :
|
|
21057
|
+
const leftPct = cw > 0 ? Math.max(0, Math.min(100, Math.round((cw - total) / cw * 100))) : -1;
|
|
20967
21058
|
const pricing = this.getPricing();
|
|
20968
21059
|
const isFreeModel = pricing.isFree || pricing.inputCostPer1M === 0 && pricing.outputCostPer1M === 0;
|
|
20969
21060
|
const data = {
|
|
@@ -20971,7 +21062,7 @@ class TokenTracker {
|
|
|
20971
21062
|
output_tokens: outputTokens,
|
|
20972
21063
|
total_tokens: total,
|
|
20973
21064
|
total_cost: this.sessionTotalCost,
|
|
20974
|
-
context_window: cw,
|
|
21065
|
+
context_window: cw > 0 ? cw : "unknown",
|
|
20975
21066
|
context_left_percent: leftPct,
|
|
20976
21067
|
provider_name: this.getDisplayName(),
|
|
20977
21068
|
updated_at: Date.now(),
|
|
@@ -21001,7 +21092,7 @@ var init_token_tracker = __esm(() => {
|
|
|
21001
21092
|
function createResponsesStreamHandler(c, response, opts) {
|
|
21002
21093
|
const reader = response.body?.getReader();
|
|
21003
21094
|
if (!reader) {
|
|
21004
|
-
return c.json(
|
|
21095
|
+
return c.json(wrapAnthropicError(500, "No response body"), 500);
|
|
21005
21096
|
}
|
|
21006
21097
|
const encoder = new TextEncoder;
|
|
21007
21098
|
const decoder = new TextDecoder;
|
|
@@ -21284,8 +21375,24 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
21284
21375
|
const encoder = new TextEncoder;
|
|
21285
21376
|
const decoder = new TextDecoder;
|
|
21286
21377
|
let isClosed = false;
|
|
21378
|
+
let lastActivity = Date.now();
|
|
21379
|
+
let pingInterval = null;
|
|
21287
21380
|
return c.body(new ReadableStream({
|
|
21288
21381
|
async start(controller) {
|
|
21382
|
+
const sendPing = () => {
|
|
21383
|
+
if (!isClosed) {
|
|
21384
|
+
controller.enqueue(encoder.encode(`event: ping
|
|
21385
|
+
data: {"type":"ping"}
|
|
21386
|
+
|
|
21387
|
+
`));
|
|
21388
|
+
}
|
|
21389
|
+
};
|
|
21390
|
+
sendPing();
|
|
21391
|
+
pingInterval = setInterval(() => {
|
|
21392
|
+
if (!isClosed && Date.now() - lastActivity > 1000) {
|
|
21393
|
+
sendPing();
|
|
21394
|
+
}
|
|
21395
|
+
}, 1000);
|
|
21289
21396
|
try {
|
|
21290
21397
|
const reader = response.body.getReader();
|
|
21291
21398
|
let buffer = "";
|
|
@@ -21300,6 +21407,7 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
21300
21407
|
if (done)
|
|
21301
21408
|
break;
|
|
21302
21409
|
buffer += decoder.decode(value, { stream: true });
|
|
21410
|
+
lastActivity = Date.now();
|
|
21303
21411
|
const lines = buffer.split(`
|
|
21304
21412
|
`);
|
|
21305
21413
|
buffer = lines.pop() || "";
|
|
@@ -21342,19 +21450,31 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
21342
21450
|
opts.onTokenUpdate(inputTokens, outputTokens);
|
|
21343
21451
|
}
|
|
21344
21452
|
if (!isClosed) {
|
|
21345
|
-
controller.close();
|
|
21346
21453
|
isClosed = true;
|
|
21454
|
+
if (pingInterval) {
|
|
21455
|
+
clearInterval(pingInterval);
|
|
21456
|
+
pingInterval = null;
|
|
21457
|
+
}
|
|
21458
|
+
controller.close();
|
|
21347
21459
|
}
|
|
21348
21460
|
} catch (e) {
|
|
21349
21461
|
log(`[AnthropicSSE] Stream error: ${e}`);
|
|
21350
21462
|
if (!isClosed) {
|
|
21351
|
-
controller.close();
|
|
21352
21463
|
isClosed = true;
|
|
21464
|
+
if (pingInterval) {
|
|
21465
|
+
clearInterval(pingInterval);
|
|
21466
|
+
pingInterval = null;
|
|
21467
|
+
}
|
|
21468
|
+
controller.close();
|
|
21353
21469
|
}
|
|
21354
21470
|
}
|
|
21355
21471
|
},
|
|
21356
21472
|
cancel() {
|
|
21357
21473
|
isClosed = true;
|
|
21474
|
+
if (pingInterval) {
|
|
21475
|
+
clearInterval(pingInterval);
|
|
21476
|
+
pingInterval = null;
|
|
21477
|
+
}
|
|
21358
21478
|
}
|
|
21359
21479
|
}), {
|
|
21360
21480
|
headers: {
|
|
@@ -22237,7 +22357,7 @@ var init_profile_config = __esm(() => {
|
|
|
22237
22357
|
});
|
|
22238
22358
|
|
|
22239
22359
|
// src/version.ts
|
|
22240
|
-
var VERSION = "6.
|
|
22360
|
+
var VERSION = "6.11.1";
|
|
22241
22361
|
|
|
22242
22362
|
// src/telemetry.ts
|
|
22243
22363
|
var exports_telemetry = {};
|
|
@@ -24218,7 +24338,7 @@ class ComposedHandler {
|
|
|
24218
24338
|
invocation_mode: this.options.invocationMode ?? "auto-route"
|
|
24219
24339
|
});
|
|
24220
24340
|
} catch {}
|
|
24221
|
-
return c.json(
|
|
24341
|
+
return c.json(wrapAnthropicError(503, msg, "connection_error"), 503);
|
|
24222
24342
|
}
|
|
24223
24343
|
throw error2;
|
|
24224
24344
|
}
|
|
@@ -24280,7 +24400,7 @@ class ComposedHandler {
|
|
|
24280
24400
|
invocation_mode: this.options.invocationMode ?? "auto-route"
|
|
24281
24401
|
});
|
|
24282
24402
|
} catch {}
|
|
24283
|
-
return c.json(
|
|
24403
|
+
return c.json(wrapAnthropicError(retryResp.status, errorText), retryResp.status);
|
|
24284
24404
|
}
|
|
24285
24405
|
} catch (err) {
|
|
24286
24406
|
log(`[${this.provider.displayName}] Auth refresh failed: ${err.message}`);
|
|
@@ -24317,7 +24437,7 @@ class ComposedHandler {
|
|
|
24317
24437
|
invocation_mode: this.options.invocationMode ?? "auto-route"
|
|
24318
24438
|
});
|
|
24319
24439
|
} catch {}
|
|
24320
|
-
return c.json(
|
|
24440
|
+
return c.json(wrapAnthropicError(401, err.message, "authentication_error"), 401);
|
|
24321
24441
|
}
|
|
24322
24442
|
} else {
|
|
24323
24443
|
const errorText = await response.text();
|
|
@@ -24370,7 +24490,7 @@ class ComposedHandler {
|
|
|
24370
24490
|
} catch {
|
|
24371
24491
|
errorBody = { error: { type: "api_error", message: errorText } };
|
|
24372
24492
|
}
|
|
24373
|
-
return c.json(errorBody, response.status);
|
|
24493
|
+
return c.json(ensureAnthropicErrorFormat(response.status, errorBody), response.status);
|
|
24374
24494
|
}
|
|
24375
24495
|
}
|
|
24376
24496
|
if (droppedParams.length > 0) {
|
|
@@ -26259,16 +26379,6 @@ var init_gemini_apikey = __esm(() => {
|
|
|
26259
26379
|
});
|
|
26260
26380
|
|
|
26261
26381
|
// src/auth/gemini-oauth.ts
|
|
26262
|
-
var exports_gemini_oauth = {};
|
|
26263
|
-
__export(exports_gemini_oauth, {
|
|
26264
|
-
setupGeminiUser: () => setupGeminiUser,
|
|
26265
|
-
retrieveUserQuota: () => retrieveUserQuota,
|
|
26266
|
-
getValidAccessToken: () => getValidAccessToken,
|
|
26267
|
-
getGeminiTierFullName: () => getGeminiTierFullName,
|
|
26268
|
-
getGeminiTierDisplayName: () => getGeminiTierDisplayName,
|
|
26269
|
-
getGeminiOAuth: () => getGeminiOAuth,
|
|
26270
|
-
GeminiOAuth: () => GeminiOAuth
|
|
26271
|
-
});
|
|
26272
26382
|
import { createServer } from "http";
|
|
26273
26383
|
import { randomBytes as randomBytes2, createHash as createHash4 } from "crypto";
|
|
26274
26384
|
import { readFileSync as readFileSync10, existsSync as existsSync13, unlinkSync as unlinkSync3, openSync, writeSync, closeSync } from "fs";
|
|
@@ -26593,9 +26703,6 @@ Please open this URL in your browser to authenticate:`);
|
|
|
26593
26703
|
}
|
|
26594
26704
|
}
|
|
26595
26705
|
}
|
|
26596
|
-
function getGeminiOAuth() {
|
|
26597
|
-
return GeminiOAuth.getInstance();
|
|
26598
|
-
}
|
|
26599
26706
|
async function getValidAccessToken() {
|
|
26600
26707
|
const oauth = GeminiOAuth.getInstance();
|
|
26601
26708
|
return oauth.getAccessToken();
|
|
@@ -26667,7 +26774,7 @@ async function setupGeminiUser(accessToken) {
|
|
|
26667
26774
|
async function callLoadCodeAssist(accessToken, projectId) {
|
|
26668
26775
|
const metadata = {
|
|
26669
26776
|
pluginType: "GEMINI",
|
|
26670
|
-
ideType: "
|
|
26777
|
+
ideType: "GEMINI_CLI",
|
|
26671
26778
|
platform: "PLATFORM_UNSPECIFIED",
|
|
26672
26779
|
duetProject: projectId
|
|
26673
26780
|
};
|
|
@@ -26687,7 +26794,7 @@ async function callLoadCodeAssist(accessToken, projectId) {
|
|
|
26687
26794
|
async function callOnboardUser(accessToken, tierId, projectId) {
|
|
26688
26795
|
const metadata = {
|
|
26689
26796
|
pluginType: "GEMINI",
|
|
26690
|
-
ideType: "
|
|
26797
|
+
ideType: "GEMINI_CLI",
|
|
26691
26798
|
platform: "PLATFORM_UNSPECIFIED",
|
|
26692
26799
|
duetProject: projectId
|
|
26693
26800
|
};
|
|
@@ -26863,12 +26970,11 @@ class GeminiCodeAssistProviderTransport {
|
|
|
26863
26970
|
};
|
|
26864
26971
|
}
|
|
26865
26972
|
async refreshAuth() {
|
|
26866
|
-
|
|
26867
|
-
|
|
26868
|
-
const { projectId, tierId } = await setupGeminiUser2(this.accessToken);
|
|
26973
|
+
this.accessToken = await getValidAccessToken();
|
|
26974
|
+
const { projectId, tierId } = await setupGeminiUser(this.accessToken);
|
|
26869
26975
|
this.projectId = projectId;
|
|
26870
26976
|
this.tierId = tierId;
|
|
26871
|
-
this._displayName =
|
|
26977
|
+
this._displayName = getGeminiTierDisplayName();
|
|
26872
26978
|
log(`[GeminiCodeAssist] Auth refreshed, project: ${this.projectId}, tier: ${this._displayName}`);
|
|
26873
26979
|
}
|
|
26874
26980
|
transformPayload(payload) {
|
|
@@ -26969,8 +27075,7 @@ class GeminiCodeAssistProviderTransport {
|
|
|
26969
27075
|
if (!this.accessToken || !this.projectId)
|
|
26970
27076
|
return;
|
|
26971
27077
|
try {
|
|
26972
|
-
const
|
|
26973
|
-
const data = await retrieveUserQuota2(this.accessToken, this.projectId);
|
|
27078
|
+
const data = await retrieveUserQuota(this.accessToken, this.projectId);
|
|
26974
27079
|
if (!data?.buckets?.length)
|
|
26975
27080
|
return;
|
|
26976
27081
|
const lines = [];
|
|
@@ -26995,8 +27100,7 @@ ${lines.join(`
|
|
|
26995
27100
|
if (!this.accessToken || !this.projectId)
|
|
26996
27101
|
return;
|
|
26997
27102
|
try {
|
|
26998
|
-
const
|
|
26999
|
-
const data = await retrieveUserQuota2(this.accessToken, this.projectId);
|
|
27103
|
+
const data = await retrieveUserQuota(this.accessToken, this.projectId);
|
|
27000
27104
|
if (!data?.buckets?.length)
|
|
27001
27105
|
return;
|
|
27002
27106
|
const bucket = data.buckets.find((b) => b.modelId === modelName);
|
|
@@ -27010,6 +27114,7 @@ var CODE_ASSIST_BASE = "https://cloudcode-pa.googleapis.com", CODE_ASSIST_ENDPOI
|
|
|
27010
27114
|
var init_gemini_codeassist = __esm(() => {
|
|
27011
27115
|
init_gemini_queue();
|
|
27012
27116
|
init_logger();
|
|
27117
|
+
init_gemini_oauth();
|
|
27013
27118
|
CODE_ASSIST_ENDPOINT = `${CODE_ASSIST_BASE}/v1internal:streamGenerateContent?alt=sse`;
|
|
27014
27119
|
CODE_ASSIST_FALLBACK_CHAIN = [
|
|
27015
27120
|
"gemini-3.1-pro-preview",
|
|
@@ -27115,12 +27220,6 @@ var init_openai = __esm(() => {
|
|
|
27115
27220
|
});
|
|
27116
27221
|
|
|
27117
27222
|
// src/auth/codex-oauth.ts
|
|
27118
|
-
var exports_codex_oauth = {};
|
|
27119
|
-
__export(exports_codex_oauth, {
|
|
27120
|
-
getValidCodexAccessToken: () => getValidCodexAccessToken,
|
|
27121
|
-
getCodexOAuth: () => getCodexOAuth,
|
|
27122
|
-
CodexOAuth: () => CodexOAuth
|
|
27123
|
-
});
|
|
27124
27223
|
import { exec as exec2 } from "child_process";
|
|
27125
27224
|
import { createHash as createHash5, randomBytes as randomBytes3 } from "crypto";
|
|
27126
27225
|
import { closeSync as closeSync2, existsSync as existsSync14, openSync as openSync2, readFileSync as readFileSync11, unlinkSync as unlinkSync4, writeSync as writeSync2 } from "fs";
|
|
@@ -27470,13 +27569,6 @@ Please open this URL in your browser to authenticate:`);
|
|
|
27470
27569
|
}
|
|
27471
27570
|
}
|
|
27472
27571
|
}
|
|
27473
|
-
function getCodexOAuth() {
|
|
27474
|
-
return CodexOAuth.getInstance();
|
|
27475
|
-
}
|
|
27476
|
-
async function getValidCodexAccessToken() {
|
|
27477
|
-
const oauth = CodexOAuth.getInstance();
|
|
27478
|
-
return oauth.getAccessToken();
|
|
27479
|
-
}
|
|
27480
27572
|
var execAsync2, OAUTH_CONFIG2;
|
|
27481
27573
|
var init_codex_oauth = __esm(() => {
|
|
27482
27574
|
init_logger();
|
|
@@ -27511,6 +27603,7 @@ var OpenAICodexTransport;
|
|
|
27511
27603
|
var init_openai_codex = __esm(() => {
|
|
27512
27604
|
init_logger();
|
|
27513
27605
|
init_openai();
|
|
27606
|
+
init_codex_oauth();
|
|
27514
27607
|
OpenAICodexTransport = class OpenAICodexTransport extends OpenAIProviderTransport {
|
|
27515
27608
|
async getHeaders() {
|
|
27516
27609
|
const oauthHeaders = await this.tryOAuthHeaders();
|
|
@@ -27528,8 +27621,7 @@ var init_openai_codex = __esm(() => {
|
|
|
27528
27621
|
return null;
|
|
27529
27622
|
const buffer = 5 * 60 * 1000;
|
|
27530
27623
|
if (creds.expires_at && Date.now() > creds.expires_at - buffer) {
|
|
27531
|
-
const
|
|
27532
|
-
const oauth = CodexOAuth2.getInstance();
|
|
27624
|
+
const oauth = CodexOAuth.getInstance();
|
|
27533
27625
|
const token = await oauth.getAccessToken();
|
|
27534
27626
|
log("[OpenAI Codex] Using refreshed OAuth token");
|
|
27535
27627
|
return buildOAuthHeaders(token, oauth.getAccountId());
|
|
@@ -27545,13 +27637,6 @@ var init_openai_codex = __esm(() => {
|
|
|
27545
27637
|
});
|
|
27546
27638
|
|
|
27547
27639
|
// src/auth/kimi-oauth.ts
|
|
27548
|
-
var exports_kimi_oauth = {};
|
|
27549
|
-
__export(exports_kimi_oauth, {
|
|
27550
|
-
hasKimiOAuthCredentials: () => hasKimiOAuthCredentials,
|
|
27551
|
-
getValidKimiAccessToken: () => getValidKimiAccessToken,
|
|
27552
|
-
getKimiOAuth: () => getKimiOAuth,
|
|
27553
|
-
KimiOAuth: () => KimiOAuth
|
|
27554
|
-
});
|
|
27555
27640
|
import { randomBytes as randomBytes4 } from "crypto";
|
|
27556
27641
|
import { readFileSync as readFileSync13, existsSync as existsSync16, unlinkSync as unlinkSync5, openSync as openSync3, writeSync as writeSync3, closeSync as closeSync3 } from "fs";
|
|
27557
27642
|
import { homedir as homedir17, hostname, platform, release } from "os";
|
|
@@ -27883,26 +27968,6 @@ Waiting for authorization...`);
|
|
|
27883
27968
|
log(`[KimiOAuth] Credentials saved to ${credPath}`);
|
|
27884
27969
|
}
|
|
27885
27970
|
}
|
|
27886
|
-
function getKimiOAuth() {
|
|
27887
|
-
return KimiOAuth.getInstance();
|
|
27888
|
-
}
|
|
27889
|
-
async function getValidKimiAccessToken() {
|
|
27890
|
-
const oauth = KimiOAuth.getInstance();
|
|
27891
|
-
return oauth.getAccessToken();
|
|
27892
|
-
}
|
|
27893
|
-
function hasKimiOAuthCredentials() {
|
|
27894
|
-
try {
|
|
27895
|
-
const credPath = join18(homedir17(), ".claudish", "kimi-oauth.json");
|
|
27896
|
-
if (!existsSync16(credPath))
|
|
27897
|
-
return false;
|
|
27898
|
-
const data = JSON.parse(readFileSync13(credPath, "utf-8"));
|
|
27899
|
-
const now = Date.now();
|
|
27900
|
-
const bufferMs = 5 * 60 * 1000;
|
|
27901
|
-
return !!(data.access_token && data.refresh_token && data.expires_at && data.expires_at > now + bufferMs);
|
|
27902
|
-
} catch {
|
|
27903
|
-
return false;
|
|
27904
|
-
}
|
|
27905
|
-
}
|
|
27906
27971
|
var execAsync3, OAUTH_CONFIG3;
|
|
27907
27972
|
var init_kimi_oauth = __esm(() => {
|
|
27908
27973
|
init_logger();
|
|
@@ -27916,6 +27981,10 @@ var init_kimi_oauth = __esm(() => {
|
|
|
27916
27981
|
});
|
|
27917
27982
|
|
|
27918
27983
|
// src/providers/transport/anthropic-compat.ts
|
|
27984
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
|
|
27985
|
+
import { join as join19 } from "path";
|
|
27986
|
+
import { homedir as homedir18 } from "os";
|
|
27987
|
+
|
|
27919
27988
|
class AnthropicProviderTransport {
|
|
27920
27989
|
name;
|
|
27921
27990
|
displayName;
|
|
@@ -27945,15 +28014,11 @@ class AnthropicProviderTransport {
|
|
|
27945
28014
|
}
|
|
27946
28015
|
if (this.provider.name === "kimi-coding" && !this.apiKey) {
|
|
27947
28016
|
try {
|
|
27948
|
-
const { existsSync: existsSync17, readFileSync: readFileSync14 } = await import("fs");
|
|
27949
|
-
const { join: join19 } = await import("path");
|
|
27950
|
-
const { homedir: homedir18 } = await import("os");
|
|
27951
28017
|
const credPath = join19(homedir18(), ".claudish", "kimi-oauth.json");
|
|
27952
28018
|
if (existsSync17(credPath)) {
|
|
27953
28019
|
const data = JSON.parse(readFileSync14(credPath, "utf-8"));
|
|
27954
28020
|
if (data.access_token && data.refresh_token) {
|
|
27955
|
-
const
|
|
27956
|
-
const oauth = KimiOAuth2.getInstance();
|
|
28021
|
+
const oauth = KimiOAuth.getInstance();
|
|
27957
28022
|
const accessToken = await oauth.getAccessToken();
|
|
27958
28023
|
delete headers["x-api-key"];
|
|
27959
28024
|
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
@@ -27981,6 +28046,7 @@ class AnthropicProviderTransport {
|
|
|
27981
28046
|
}
|
|
27982
28047
|
var init_anthropic_compat = __esm(() => {
|
|
27983
28048
|
init_logger();
|
|
28049
|
+
init_kimi_oauth();
|
|
27984
28050
|
});
|
|
27985
28051
|
|
|
27986
28052
|
// src/adapters/anthropic-api-format.ts
|
|
@@ -28071,7 +28137,7 @@ var init_anthropic_api_format = __esm(() => {
|
|
|
28071
28137
|
return 131072;
|
|
28072
28138
|
if (this.providerName === "minimax" || this.providerName === "minimax-coding")
|
|
28073
28139
|
return 204800;
|
|
28074
|
-
return
|
|
28140
|
+
return 0;
|
|
28075
28141
|
}
|
|
28076
28142
|
supportsVision() {
|
|
28077
28143
|
return true;
|
|
@@ -28251,13 +28317,14 @@ var init_litellm2 = __esm(() => {
|
|
|
28251
28317
|
});
|
|
28252
28318
|
|
|
28253
28319
|
// src/adapters/litellm-api-format.ts
|
|
28254
|
-
import { existsSync as
|
|
28320
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
|
|
28255
28321
|
import { createHash as createHash6 } from "crypto";
|
|
28256
|
-
import { homedir as
|
|
28257
|
-
import { join as
|
|
28322
|
+
import { homedir as homedir19 } from "os";
|
|
28323
|
+
import { join as join20 } from "path";
|
|
28258
28324
|
var INLINE_IMAGE_MODEL_PATTERNS, LiteLLMAPIFormat;
|
|
28259
28325
|
var init_litellm_api_format = __esm(() => {
|
|
28260
28326
|
init_base_api_format();
|
|
28327
|
+
init_model_catalog();
|
|
28261
28328
|
init_logger();
|
|
28262
28329
|
INLINE_IMAGE_MODEL_PATTERNS = ["minimax"];
|
|
28263
28330
|
LiteLLMAPIFormat = class LiteLLMAPIFormat extends DefaultAPIFormat {
|
|
@@ -28345,15 +28412,15 @@ var init_litellm_api_format = __esm(() => {
|
|
|
28345
28412
|
return payload;
|
|
28346
28413
|
}
|
|
28347
28414
|
getContextWindow() {
|
|
28348
|
-
return
|
|
28415
|
+
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
28349
28416
|
}
|
|
28350
28417
|
checkVisionSupport() {
|
|
28351
28418
|
try {
|
|
28352
28419
|
const hash = createHash6("sha256").update(this.baseUrl).digest("hex").substring(0, 16);
|
|
28353
|
-
const cachePath =
|
|
28354
|
-
if (!
|
|
28420
|
+
const cachePath = join20(homedir19(), ".claudish", `litellm-models-${hash}.json`);
|
|
28421
|
+
if (!existsSync18(cachePath))
|
|
28355
28422
|
return true;
|
|
28356
|
-
const cacheData = JSON.parse(
|
|
28423
|
+
const cacheData = JSON.parse(readFileSync15(cachePath, "utf-8"));
|
|
28357
28424
|
const model = cacheData.models?.find((m) => m.name === this.modelId);
|
|
28358
28425
|
if (model && model.supportsVision === false) {
|
|
28359
28426
|
log(`[LiteLLMAPIFormat] Model ${this.modelId} does not support vision`);
|
|
@@ -28370,9 +28437,9 @@ var init_litellm_api_format = __esm(() => {
|
|
|
28370
28437
|
// src/auth/vertex-auth.ts
|
|
28371
28438
|
import { exec as exec4 } from "child_process";
|
|
28372
28439
|
import { promisify as promisify4 } from "util";
|
|
28373
|
-
import { existsSync as
|
|
28374
|
-
import { homedir as
|
|
28375
|
-
import { join as
|
|
28440
|
+
import { existsSync as existsSync19 } from "fs";
|
|
28441
|
+
import { homedir as homedir20 } from "os";
|
|
28442
|
+
import { join as join21 } from "path";
|
|
28376
28443
|
|
|
28377
28444
|
class VertexAuthManager {
|
|
28378
28445
|
cachedToken = null;
|
|
@@ -28426,8 +28493,8 @@ class VertexAuthManager {
|
|
|
28426
28493
|
}
|
|
28427
28494
|
async tryADC() {
|
|
28428
28495
|
try {
|
|
28429
|
-
const adcPath =
|
|
28430
|
-
if (!
|
|
28496
|
+
const adcPath = join21(homedir20(), ".config/gcloud/application_default_credentials.json");
|
|
28497
|
+
if (!existsSync19(adcPath)) {
|
|
28431
28498
|
log("[VertexAuth] ADC credentials file not found");
|
|
28432
28499
|
return null;
|
|
28433
28500
|
}
|
|
@@ -28451,7 +28518,7 @@ class VertexAuthManager {
|
|
|
28451
28518
|
if (!credPath) {
|
|
28452
28519
|
return null;
|
|
28453
28520
|
}
|
|
28454
|
-
if (!
|
|
28521
|
+
if (!existsSync19(credPath)) {
|
|
28455
28522
|
throw new Error(`Service account file not found: ${credPath}
|
|
28456
28523
|
|
|
28457
28524
|
Check GOOGLE_APPLICATION_CREDENTIALS path.`);
|
|
@@ -28490,8 +28557,8 @@ function validateVertexOAuthConfig() {
|
|
|
28490
28557
|
` + ` export VERTEX_PROJECT='your-gcp-project-id'
|
|
28491
28558
|
` + " export VERTEX_LOCATION='us-central1' # optional";
|
|
28492
28559
|
}
|
|
28493
|
-
const adcPath =
|
|
28494
|
-
const hasADC =
|
|
28560
|
+
const adcPath = join21(homedir20(), ".config/gcloud/application_default_credentials.json");
|
|
28561
|
+
const hasADC = existsSync19(adcPath);
|
|
28495
28562
|
const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
28496
28563
|
if (!hasADC && !hasServiceAccount) {
|
|
28497
28564
|
return `No Vertex AI credentials found.
|
|
@@ -28597,9 +28664,9 @@ var init_vertex_oauth = __esm(() => {
|
|
|
28597
28664
|
});
|
|
28598
28665
|
|
|
28599
28666
|
// src/providers/api-key-provenance.ts
|
|
28600
|
-
import { existsSync as
|
|
28601
|
-
import { join as
|
|
28602
|
-
import { homedir as
|
|
28667
|
+
import { existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
|
|
28668
|
+
import { join as join22, resolve as resolve2 } from "path";
|
|
28669
|
+
import { homedir as homedir21 } from "os";
|
|
28603
28670
|
function maskKey(key) {
|
|
28604
28671
|
if (!key)
|
|
28605
28672
|
return null;
|
|
@@ -28684,9 +28751,9 @@ function formatProvenanceProbe(p, indent = " ") {
|
|
|
28684
28751
|
function readDotenvKey(envVars) {
|
|
28685
28752
|
try {
|
|
28686
28753
|
const dotenvPath = resolve2(".env");
|
|
28687
|
-
if (!
|
|
28754
|
+
if (!existsSync20(dotenvPath))
|
|
28688
28755
|
return null;
|
|
28689
|
-
const parsed = import_dotenv.parse(
|
|
28756
|
+
const parsed = import_dotenv.parse(readFileSync17(dotenvPath, "utf-8"));
|
|
28690
28757
|
for (const v of envVars) {
|
|
28691
28758
|
if (parsed[v])
|
|
28692
28759
|
return parsed[v];
|
|
@@ -28698,10 +28765,10 @@ function readDotenvKey(envVars) {
|
|
|
28698
28765
|
}
|
|
28699
28766
|
function readConfigKey(envVar) {
|
|
28700
28767
|
try {
|
|
28701
|
-
const configPath =
|
|
28702
|
-
if (!
|
|
28768
|
+
const configPath = join22(homedir21(), ".claudish", "config.json");
|
|
28769
|
+
if (!existsSync20(configPath))
|
|
28703
28770
|
return null;
|
|
28704
|
-
const cfg = JSON.parse(
|
|
28771
|
+
const cfg = JSON.parse(readFileSync17(configPath, "utf-8"));
|
|
28705
28772
|
return cfg.apiKeys?.[envVar] || null;
|
|
28706
28773
|
} catch {
|
|
28707
28774
|
return null;
|
|
@@ -29224,7 +29291,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
29224
29291
|
return c.json({ input_tokens: Math.ceil(txt.length / 4) });
|
|
29225
29292
|
}
|
|
29226
29293
|
} catch (e) {
|
|
29227
|
-
return c.json(
|
|
29294
|
+
return c.json(wrapAnthropicError(500, String(e)), 500);
|
|
29228
29295
|
}
|
|
29229
29296
|
});
|
|
29230
29297
|
app.post("/v1/messages", async (c) => {
|
|
@@ -29234,7 +29301,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
29234
29301
|
return handler.handle(c, body);
|
|
29235
29302
|
} catch (e) {
|
|
29236
29303
|
log(`[Proxy] Error: ${e}`);
|
|
29237
|
-
return c.json(
|
|
29304
|
+
return c.json(wrapAnthropicError(500, String(e)), 500);
|
|
29238
29305
|
}
|
|
29239
29306
|
});
|
|
29240
29307
|
const server = serve({ fetch: app.fetch, port, hostname: "127.0.0.1" });
|
|
@@ -29319,14 +29386,22 @@ var exports_mcp_server = {};
|
|
|
29319
29386
|
__export(exports_mcp_server, {
|
|
29320
29387
|
startMcpServer: () => startMcpServer
|
|
29321
29388
|
});
|
|
29322
|
-
import { readFileSync as
|
|
29323
|
-
import { join as
|
|
29324
|
-
import { homedir as
|
|
29389
|
+
import { readFileSync as readFileSync18, existsSync as existsSync21, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readdirSync as readdirSync3 } from "fs";
|
|
29390
|
+
import { join as join23, dirname as dirname2 } from "path";
|
|
29391
|
+
import { homedir as homedir22 } from "os";
|
|
29325
29392
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
29326
29393
|
function loadRecommendedModels() {
|
|
29327
|
-
|
|
29394
|
+
const cachedPath = join23(CLAUDISH_CACHE_DIR, "recommended-models-cache.json");
|
|
29395
|
+
if (existsSync21(cachedPath)) {
|
|
29328
29396
|
try {
|
|
29329
|
-
const data = JSON.parse(
|
|
29397
|
+
const data = JSON.parse(readFileSync18(cachedPath, "utf-8"));
|
|
29398
|
+
if (data.models && data.models.length > 0)
|
|
29399
|
+
return data.models;
|
|
29400
|
+
} catch {}
|
|
29401
|
+
}
|
|
29402
|
+
if (existsSync21(RECOMMENDED_MODELS_PATH)) {
|
|
29403
|
+
try {
|
|
29404
|
+
const data = JSON.parse(readFileSync18(RECOMMENDED_MODELS_PATH, "utf-8"));
|
|
29330
29405
|
return data.models || [];
|
|
29331
29406
|
} catch {
|
|
29332
29407
|
return [];
|
|
@@ -29334,10 +29409,28 @@ function loadRecommendedModels() {
|
|
|
29334
29409
|
}
|
|
29335
29410
|
return [];
|
|
29336
29411
|
}
|
|
29412
|
+
function parsePriceAvg(s) {
|
|
29413
|
+
if (!s || s === "N/A")
|
|
29414
|
+
return Infinity;
|
|
29415
|
+
if (s === "FREE")
|
|
29416
|
+
return 0;
|
|
29417
|
+
const m = s.match(/\$([\d.]+)/);
|
|
29418
|
+
return m ? parseFloat(m[1]) : Infinity;
|
|
29419
|
+
}
|
|
29420
|
+
function parseCtx(s) {
|
|
29421
|
+
if (!s || s === "N/A")
|
|
29422
|
+
return 0;
|
|
29423
|
+
const upper = s.toUpperCase();
|
|
29424
|
+
if (upper.includes("M"))
|
|
29425
|
+
return parseFloat(upper) * 1e6;
|
|
29426
|
+
if (upper.includes("K"))
|
|
29427
|
+
return parseFloat(upper) * 1000;
|
|
29428
|
+
return parseInt(s) || 0;
|
|
29429
|
+
}
|
|
29337
29430
|
async function loadAllModels(forceRefresh = false) {
|
|
29338
|
-
if (!forceRefresh &&
|
|
29431
|
+
if (!forceRefresh && existsSync21(ALL_MODELS_CACHE_PATH)) {
|
|
29339
29432
|
try {
|
|
29340
|
-
const cacheData = JSON.parse(
|
|
29433
|
+
const cacheData = JSON.parse(readFileSync18(ALL_MODELS_CACHE_PATH, "utf-8"));
|
|
29341
29434
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
29342
29435
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
29343
29436
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -29355,8 +29448,8 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
29355
29448
|
writeFileSync10(ALL_MODELS_CACHE_PATH, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
29356
29449
|
return models;
|
|
29357
29450
|
} catch {
|
|
29358
|
-
if (
|
|
29359
|
-
const cacheData = JSON.parse(
|
|
29451
|
+
if (existsSync21(ALL_MODELS_CACHE_PATH)) {
|
|
29452
|
+
const cacheData = JSON.parse(readFileSync18(ALL_MODELS_CACHE_PATH, "utf-8"));
|
|
29360
29453
|
return cacheData.models || [];
|
|
29361
29454
|
}
|
|
29362
29455
|
return [];
|
|
@@ -29589,12 +29682,26 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
|
|
|
29589
29682
|
output += `
|
|
29590
29683
|
## Quick Picks
|
|
29591
29684
|
`;
|
|
29592
|
-
|
|
29593
|
-
|
|
29594
|
-
|
|
29595
|
-
|
|
29596
|
-
|
|
29597
|
-
|
|
29685
|
+
const cheapest = [...models].sort((a, b) => parsePriceAvg(a.pricing?.average) - parsePriceAvg(b.pricing?.average))[0];
|
|
29686
|
+
const bigCtx = [...models].sort((a, b) => parseCtx(b.context) - parseCtx(a.context))[0];
|
|
29687
|
+
const priciest = [...models].sort((a, b) => parsePriceAvg(b.pricing?.average) - parsePriceAvg(a.pricing?.average))[0];
|
|
29688
|
+
const vision = models.find((m) => m.supportsVision);
|
|
29689
|
+
const reasoning = models.find((m) => m.supportsReasoning && m.id !== priciest?.id);
|
|
29690
|
+
if (cheapest)
|
|
29691
|
+
output += `- **Budget**: \`${cheapest.id}\` (${cheapest.pricing?.average || "N/A"})
|
|
29692
|
+
`;
|
|
29693
|
+
if (bigCtx && bigCtx.id !== cheapest?.id)
|
|
29694
|
+
output += `- **Large context**: \`${bigCtx.id}\` (${bigCtx.context || "N/A"} tokens)
|
|
29695
|
+
`;
|
|
29696
|
+
if (priciest && priciest.id !== cheapest?.id)
|
|
29697
|
+
output += `- **Most advanced**: \`${priciest.id}\` (${priciest.pricing?.average || "N/A"})
|
|
29698
|
+
`;
|
|
29699
|
+
if (vision && vision.id !== cheapest?.id && vision.id !== priciest?.id)
|
|
29700
|
+
output += `- **Vision + coding**: \`${vision.id}\` (${vision.pricing?.average || "N/A"})
|
|
29701
|
+
`;
|
|
29702
|
+
if (reasoning && reasoning.id !== cheapest?.id)
|
|
29703
|
+
output += `- **Agentic**: \`${reasoning.id}\` (${reasoning.pricing?.average || "N/A"})
|
|
29704
|
+
`;
|
|
29598
29705
|
return { content: [{ type: "text", text: output }] };
|
|
29599
29706
|
}
|
|
29600
29707
|
});
|
|
@@ -29856,7 +29963,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
29856
29963
|
let stderrFull = stderr_snippet || "";
|
|
29857
29964
|
if (error_log_path) {
|
|
29858
29965
|
try {
|
|
29859
|
-
stderrFull =
|
|
29966
|
+
stderrFull = readFileSync18(error_log_path, "utf-8");
|
|
29860
29967
|
} catch {}
|
|
29861
29968
|
}
|
|
29862
29969
|
let sessionData = {};
|
|
@@ -29864,16 +29971,16 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
29864
29971
|
const sp = session_path;
|
|
29865
29972
|
for (const file of ["status.json", "manifest.json", "input.md"]) {
|
|
29866
29973
|
try {
|
|
29867
|
-
sessionData[file] =
|
|
29974
|
+
sessionData[file] = readFileSync18(join23(sp, file), "utf-8");
|
|
29868
29975
|
} catch {}
|
|
29869
29976
|
}
|
|
29870
29977
|
try {
|
|
29871
|
-
const errorDir =
|
|
29872
|
-
if (
|
|
29978
|
+
const errorDir = join23(sp, "errors");
|
|
29979
|
+
if (existsSync21(errorDir)) {
|
|
29873
29980
|
for (const f of readdirSync3(errorDir)) {
|
|
29874
29981
|
if (f.endsWith(".log")) {
|
|
29875
29982
|
try {
|
|
29876
|
-
sessionData[`errors/${f}`] =
|
|
29983
|
+
sessionData[`errors/${f}`] = readFileSync18(join23(errorDir, f), "utf-8");
|
|
29877
29984
|
} catch {}
|
|
29878
29985
|
}
|
|
29879
29986
|
}
|
|
@@ -29883,7 +29990,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
29883
29990
|
for (const f of readdirSync3(sp)) {
|
|
29884
29991
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
29885
29992
|
try {
|
|
29886
|
-
const content =
|
|
29993
|
+
const content = readFileSync18(join23(sp, f), "utf-8");
|
|
29887
29994
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
29888
29995
|
} catch {}
|
|
29889
29996
|
}
|
|
@@ -29892,9 +29999,9 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
29892
29999
|
}
|
|
29893
30000
|
let version2 = "unknown";
|
|
29894
30001
|
try {
|
|
29895
|
-
const pkgPath =
|
|
29896
|
-
if (
|
|
29897
|
-
version2 = JSON.parse(
|
|
30002
|
+
const pkgPath = join23(__dirname3, "../package.json");
|
|
30003
|
+
if (existsSync21(pkgPath)) {
|
|
30004
|
+
version2 = JSON.parse(readFileSync18(pkgPath, "utf-8")).version;
|
|
29898
30005
|
}
|
|
29899
30006
|
} catch {}
|
|
29900
30007
|
const report = {
|
|
@@ -30255,9 +30362,9 @@ var init_mcp_server = __esm(() => {
|
|
|
30255
30362
|
import_dotenv2.config();
|
|
30256
30363
|
__filename3 = fileURLToPath2(import.meta.url);
|
|
30257
30364
|
__dirname3 = dirname2(__filename3);
|
|
30258
|
-
RECOMMENDED_MODELS_PATH =
|
|
30259
|
-
CLAUDISH_CACHE_DIR =
|
|
30260
|
-
ALL_MODELS_CACHE_PATH =
|
|
30365
|
+
RECOMMENDED_MODELS_PATH = join23(__dirname3, "../recommended-models.json");
|
|
30366
|
+
CLAUDISH_CACHE_DIR = join23(homedir22(), ".claudish");
|
|
30367
|
+
ALL_MODELS_CACHE_PATH = join23(CLAUDISH_CACHE_DIR, "all-models.json");
|
|
30261
30368
|
});
|
|
30262
30369
|
|
|
30263
30370
|
// ../../node_modules/.bun/@inquirer+core@11.0.1+04f2146be16c61ef/node_modules/@inquirer/core/dist/lib/key.js
|
|
@@ -41531,7 +41638,7 @@ var init_RemoveFileError = __esm(() => {
|
|
|
41531
41638
|
|
|
41532
41639
|
// ../../node_modules/.bun/@inquirer+external-editor@2.0.1+04f2146be16c61ef/node_modules/@inquirer/external-editor/dist/index.js
|
|
41533
41640
|
import { spawn as spawn3, spawnSync } from "child_process";
|
|
41534
|
-
import { readFileSync as
|
|
41641
|
+
import { readFileSync as readFileSync19, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
|
|
41535
41642
|
import path from "path";
|
|
41536
41643
|
import os from "os";
|
|
41537
41644
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
@@ -41647,7 +41754,7 @@ class ExternalEditor {
|
|
|
41647
41754
|
}
|
|
41648
41755
|
readTemporaryFile() {
|
|
41649
41756
|
try {
|
|
41650
|
-
const tempFileBuffer =
|
|
41757
|
+
const tempFileBuffer = readFileSync19(this.tempFile);
|
|
41651
41758
|
if (tempFileBuffer.length === 0) {
|
|
41652
41759
|
this.text = "";
|
|
41653
41760
|
} else {
|
|
@@ -42658,8 +42765,7 @@ async function loginCommand(providerArg) {
|
|
|
42658
42765
|
process.exit(1);
|
|
42659
42766
|
}
|
|
42660
42767
|
try {
|
|
42661
|
-
const
|
|
42662
|
-
const oauth = mod[provider.className].getInstance();
|
|
42768
|
+
const oauth = provider.getInstance();
|
|
42663
42769
|
await oauth.login();
|
|
42664
42770
|
console.log(`
|
|
42665
42771
|
\u2705 ${provider.displayName} OAuth login successful!`);
|
|
@@ -42679,8 +42785,7 @@ async function logoutCommand(providerArg) {
|
|
|
42679
42785
|
process.exit(1);
|
|
42680
42786
|
}
|
|
42681
42787
|
try {
|
|
42682
|
-
const
|
|
42683
|
-
const oauth = mod[provider.className].getInstance();
|
|
42788
|
+
const oauth = provider.getInstance();
|
|
42684
42789
|
await oauth.logout();
|
|
42685
42790
|
console.log(`\u2705 ${provider.displayName} OAuth credentials cleared.`);
|
|
42686
42791
|
process.exit(0);
|
|
@@ -42693,29 +42798,29 @@ var AUTH_PROVIDERS;
|
|
|
42693
42798
|
var init_auth_commands = __esm(() => {
|
|
42694
42799
|
init_dist17();
|
|
42695
42800
|
init_oauth_registry();
|
|
42801
|
+
init_gemini_oauth();
|
|
42802
|
+
init_kimi_oauth();
|
|
42803
|
+
init_codex_oauth();
|
|
42696
42804
|
AUTH_PROVIDERS = [
|
|
42697
42805
|
{
|
|
42698
42806
|
name: "gemini",
|
|
42699
42807
|
displayName: "Gemini Code Assist",
|
|
42700
42808
|
prefix: "go@",
|
|
42701
|
-
|
|
42702
|
-
className: "GeminiOAuth",
|
|
42809
|
+
getInstance: () => GeminiOAuth.getInstance(),
|
|
42703
42810
|
registryKeys: ["google", "gemini-codeassist"]
|
|
42704
42811
|
},
|
|
42705
42812
|
{
|
|
42706
42813
|
name: "kimi",
|
|
42707
42814
|
displayName: "Kimi / Moonshot AI",
|
|
42708
42815
|
prefix: "kc@, kimi@",
|
|
42709
|
-
|
|
42710
|
-
className: "KimiOAuth",
|
|
42816
|
+
getInstance: () => KimiOAuth.getInstance(),
|
|
42711
42817
|
registryKeys: ["kimi", "kimi-coding"]
|
|
42712
42818
|
},
|
|
42713
42819
|
{
|
|
42714
42820
|
name: "codex",
|
|
42715
42821
|
displayName: "OpenAI Codex (ChatGPT Plus/Pro)",
|
|
42716
42822
|
prefix: "cx@",
|
|
42717
|
-
|
|
42718
|
-
className: "CodexOAuth",
|
|
42823
|
+
getInstance: () => CodexOAuth.getInstance(),
|
|
42719
42824
|
registryKeys: ["openai-codex"]
|
|
42720
42825
|
}
|
|
42721
42826
|
];
|
|
@@ -42756,11 +42861,10 @@ async function geminiQuotaHandler() {
|
|
|
42756
42861
|
process.exit(1);
|
|
42757
42862
|
}
|
|
42758
42863
|
try {
|
|
42759
|
-
const
|
|
42760
|
-
const
|
|
42761
|
-
const
|
|
42762
|
-
const
|
|
42763
|
-
const quota = await retrieveUserQuota2(accessToken, projectId);
|
|
42864
|
+
const accessToken = await getValidAccessToken();
|
|
42865
|
+
const { projectId } = await setupGeminiUser(accessToken);
|
|
42866
|
+
const tierName = getGeminiTierFullName();
|
|
42867
|
+
const quota = await retrieveUserQuota(accessToken, projectId);
|
|
42764
42868
|
if (!quota?.buckets?.length) {
|
|
42765
42869
|
console.log(`
|
|
42766
42870
|
${D}No quota data available.${R}
|
|
@@ -42828,15 +42932,15 @@ async function geminiQuotaHandler() {
|
|
|
42828
42932
|
}
|
|
42829
42933
|
}
|
|
42830
42934
|
async function codexQuotaHandler() {
|
|
42831
|
-
const { readFileSync:
|
|
42832
|
-
const { join:
|
|
42833
|
-
const { homedir:
|
|
42834
|
-
const credPath =
|
|
42835
|
-
if (!
|
|
42935
|
+
const { readFileSync: readFileSync20, existsSync: existsSync22 } = await import("fs");
|
|
42936
|
+
const { join: join24 } = await import("path");
|
|
42937
|
+
const { homedir: homedir23 } = await import("os");
|
|
42938
|
+
const credPath = join24(homedir23(), ".claudish", "codex-oauth.json");
|
|
42939
|
+
if (!existsSync22(credPath)) {
|
|
42836
42940
|
console.error(`${RED}No Codex credentials found.${R} Run: ${B}claudish login codex${R}`);
|
|
42837
42941
|
process.exit(1);
|
|
42838
42942
|
}
|
|
42839
|
-
const creds = JSON.parse(
|
|
42943
|
+
const creds = JSON.parse(readFileSync20(credPath, "utf-8"));
|
|
42840
42944
|
let email2 = "";
|
|
42841
42945
|
try {
|
|
42842
42946
|
const parts = creds.access_token.split(".");
|
|
@@ -42882,9 +42986,9 @@ async function codexQuotaHandler() {
|
|
|
42882
42986
|
}
|
|
42883
42987
|
let modelSlugs = [];
|
|
42884
42988
|
try {
|
|
42885
|
-
const modelsPath =
|
|
42886
|
-
if (
|
|
42887
|
-
const cache = JSON.parse(
|
|
42989
|
+
const modelsPath = join24(homedir23(), ".codex", "models_cache.json");
|
|
42990
|
+
if (existsSync22(modelsPath)) {
|
|
42991
|
+
const cache = JSON.parse(readFileSync20(modelsPath, "utf-8"));
|
|
42888
42992
|
modelSlugs = (cache.models || []).map((m) => m.slug || m.id).filter(Boolean);
|
|
42889
42993
|
}
|
|
42890
42994
|
} catch {}
|
|
@@ -42990,6 +43094,7 @@ function formatRelativeReset(resetTime) {
|
|
|
42990
43094
|
var R = "\x1B[0m", B = "\x1B[1m", D = "\x1B[2m", I = "\x1B[3m", RED = "\x1B[31m", GRN = "\x1B[32m", YEL = "\x1B[33m", MAG = "\x1B[35m", CYN = "\x1B[36m", WHT = "\x1B[37m", GRY = "\x1B[90m", FALLBACK_CHAIN, QUOTA_ADAPTERS;
|
|
42991
43095
|
var init_quota_command = __esm(() => {
|
|
42992
43096
|
init_oauth_registry();
|
|
43097
|
+
init_gemini_oauth();
|
|
42993
43098
|
FALLBACK_CHAIN = [
|
|
42994
43099
|
"gemini-3.1-pro-preview",
|
|
42995
43100
|
"gemini-3-pro-preview",
|
|
@@ -43114,23 +43219,23 @@ __export(exports_cli, {
|
|
|
43114
43219
|
getMissingKeyError: () => getMissingKeyError
|
|
43115
43220
|
});
|
|
43116
43221
|
import {
|
|
43117
|
-
readFileSync as
|
|
43222
|
+
readFileSync as readFileSync20,
|
|
43118
43223
|
writeFileSync as writeFileSync12,
|
|
43119
|
-
existsSync as
|
|
43224
|
+
existsSync as existsSync22,
|
|
43120
43225
|
mkdirSync as mkdirSync11,
|
|
43121
43226
|
copyFileSync,
|
|
43122
43227
|
readdirSync as readdirSync4,
|
|
43123
43228
|
unlinkSync as unlinkSync7
|
|
43124
43229
|
} from "fs";
|
|
43125
43230
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
43126
|
-
import { dirname as dirname3, join as
|
|
43127
|
-
import { homedir as
|
|
43231
|
+
import { dirname as dirname3, join as join24 } from "path";
|
|
43232
|
+
import { homedir as homedir23 } from "os";
|
|
43128
43233
|
function getVersion3() {
|
|
43129
43234
|
return VERSION;
|
|
43130
43235
|
}
|
|
43131
43236
|
function clearAllModelCaches() {
|
|
43132
|
-
const cacheDir =
|
|
43133
|
-
if (!
|
|
43237
|
+
const cacheDir = join24(homedir23(), ".claudish");
|
|
43238
|
+
if (!existsSync22(cacheDir))
|
|
43134
43239
|
return;
|
|
43135
43240
|
const cachePatterns = ["all-models.json", "pricing-cache.json"];
|
|
43136
43241
|
let cleared = 0;
|
|
@@ -43138,7 +43243,7 @@ function clearAllModelCaches() {
|
|
|
43138
43243
|
const files = readdirSync4(cacheDir);
|
|
43139
43244
|
for (const file of files) {
|
|
43140
43245
|
if (cachePatterns.includes(file) || file.startsWith("litellm-models-")) {
|
|
43141
|
-
unlinkSync7(
|
|
43246
|
+
unlinkSync7(join24(cacheDir, file));
|
|
43142
43247
|
cleared++;
|
|
43143
43248
|
}
|
|
43144
43249
|
}
|
|
@@ -43460,9 +43565,9 @@ async function fetchOllamaModels() {
|
|
|
43460
43565
|
}
|
|
43461
43566
|
async function searchAndPrintModels(query, forceUpdate) {
|
|
43462
43567
|
let models = [];
|
|
43463
|
-
if (!forceUpdate &&
|
|
43568
|
+
if (!forceUpdate && existsSync22(ALL_MODELS_JSON_PATH)) {
|
|
43464
43569
|
try {
|
|
43465
|
-
const cacheData = JSON.parse(
|
|
43570
|
+
const cacheData = JSON.parse(readFileSync20(ALL_MODELS_JSON_PATH, "utf-8"));
|
|
43466
43571
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
43467
43572
|
const now = new Date;
|
|
43468
43573
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -43630,9 +43735,9 @@ Found ${results.length} matching models:
|
|
|
43630
43735
|
async function printAllModels(jsonOutput, forceUpdate) {
|
|
43631
43736
|
let models = [];
|
|
43632
43737
|
const [ollamaModels, zenModels] = await Promise.all([fetchOllamaModels(), fetchZenModels()]);
|
|
43633
|
-
if (!forceUpdate &&
|
|
43738
|
+
if (!forceUpdate && existsSync22(ALL_MODELS_JSON_PATH)) {
|
|
43634
43739
|
try {
|
|
43635
|
-
const cacheData = JSON.parse(
|
|
43740
|
+
const cacheData = JSON.parse(readFileSync20(ALL_MODELS_JSON_PATH, "utf-8"));
|
|
43636
43741
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
43637
43742
|
const now = new Date;
|
|
43638
43743
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -43833,12 +43938,12 @@ async function printAllModels(jsonOutput, forceUpdate) {
|
|
|
43833
43938
|
console.log("Top models: claudish --top-models");
|
|
43834
43939
|
}
|
|
43835
43940
|
function isCacheStale() {
|
|
43836
|
-
const cachePath =
|
|
43837
|
-
if (!
|
|
43941
|
+
const cachePath = existsSync22(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
43942
|
+
if (!existsSync22(cachePath)) {
|
|
43838
43943
|
return true;
|
|
43839
43944
|
}
|
|
43840
43945
|
try {
|
|
43841
|
-
const jsonContent =
|
|
43946
|
+
const jsonContent = readFileSync20(cachePath, "utf-8");
|
|
43842
43947
|
const data = JSON.parse(jsonContent);
|
|
43843
43948
|
if (!data.lastUpdated) {
|
|
43844
43949
|
return true;
|
|
@@ -43917,10 +44022,10 @@ async function updateModelsFromOpenRouter() {
|
|
|
43917
44022
|
providers.add(provider);
|
|
43918
44023
|
}
|
|
43919
44024
|
let version2 = "1.2.0";
|
|
43920
|
-
const existingPath =
|
|
43921
|
-
if (
|
|
44025
|
+
const existingPath = existsSync22(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
44026
|
+
if (existsSync22(existingPath)) {
|
|
43922
44027
|
try {
|
|
43923
|
-
const existing = JSON.parse(
|
|
44028
|
+
const existing = JSON.parse(readFileSync20(existingPath, "utf-8"));
|
|
43924
44029
|
version2 = existing.version || version2;
|
|
43925
44030
|
} catch {}
|
|
43926
44031
|
}
|
|
@@ -43949,8 +44054,8 @@ async function checkAndUpdateModelsCache(forceUpdate = false) {
|
|
|
43949
44054
|
await updateModelsFromOpenRouter();
|
|
43950
44055
|
} else {
|
|
43951
44056
|
try {
|
|
43952
|
-
const cachePath =
|
|
43953
|
-
const data = JSON.parse(
|
|
44057
|
+
const cachePath = existsSync22(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
44058
|
+
const data = JSON.parse(readFileSync20(cachePath, "utf-8"));
|
|
43954
44059
|
console.error(`\u2713 Using cached models (last updated: ${data.lastUpdated})`);
|
|
43955
44060
|
} catch {}
|
|
43956
44061
|
}
|
|
@@ -44548,8 +44653,8 @@ MORE INFO:
|
|
|
44548
44653
|
}
|
|
44549
44654
|
function printAIAgentGuide() {
|
|
44550
44655
|
try {
|
|
44551
|
-
const guidePath =
|
|
44552
|
-
const guideContent =
|
|
44656
|
+
const guidePath = join24(__dirname4, "../AI_AGENT_GUIDE.md");
|
|
44657
|
+
const guideContent = readFileSync20(guidePath, "utf-8");
|
|
44553
44658
|
console.log(guideContent);
|
|
44554
44659
|
} catch (error2) {
|
|
44555
44660
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -44565,19 +44670,19 @@ async function initializeClaudishSkill() {
|
|
|
44565
44670
|
console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
|
|
44566
44671
|
`);
|
|
44567
44672
|
const cwd = process.cwd();
|
|
44568
|
-
const claudeDir =
|
|
44569
|
-
const skillsDir =
|
|
44570
|
-
const claudishSkillDir =
|
|
44571
|
-
const skillFile =
|
|
44572
|
-
if (
|
|
44673
|
+
const claudeDir = join24(cwd, ".claude");
|
|
44674
|
+
const skillsDir = join24(claudeDir, "skills");
|
|
44675
|
+
const claudishSkillDir = join24(skillsDir, "claudish-usage");
|
|
44676
|
+
const skillFile = join24(claudishSkillDir, "SKILL.md");
|
|
44677
|
+
if (existsSync22(skillFile)) {
|
|
44573
44678
|
console.log("\u2705 Claudish skill already installed at:");
|
|
44574
44679
|
console.log(` ${skillFile}
|
|
44575
44680
|
`);
|
|
44576
44681
|
console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
|
|
44577
44682
|
return;
|
|
44578
44683
|
}
|
|
44579
|
-
const sourceSkillPath =
|
|
44580
|
-
if (!
|
|
44684
|
+
const sourceSkillPath = join24(__dirname4, "../skills/claudish-usage/SKILL.md");
|
|
44685
|
+
if (!existsSync22(sourceSkillPath)) {
|
|
44581
44686
|
console.error("\u274C Error: Claudish skill file not found in installation.");
|
|
44582
44687
|
console.error(` Expected at: ${sourceSkillPath}`);
|
|
44583
44688
|
console.error(`
|
|
@@ -44586,15 +44691,15 @@ async function initializeClaudishSkill() {
|
|
|
44586
44691
|
process.exit(1);
|
|
44587
44692
|
}
|
|
44588
44693
|
try {
|
|
44589
|
-
if (!
|
|
44694
|
+
if (!existsSync22(claudeDir)) {
|
|
44590
44695
|
mkdirSync11(claudeDir, { recursive: true });
|
|
44591
44696
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
44592
44697
|
}
|
|
44593
|
-
if (!
|
|
44698
|
+
if (!existsSync22(skillsDir)) {
|
|
44594
44699
|
mkdirSync11(skillsDir, { recursive: true });
|
|
44595
44700
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
44596
44701
|
}
|
|
44597
|
-
if (!
|
|
44702
|
+
if (!existsSync22(claudishSkillDir)) {
|
|
44598
44703
|
mkdirSync11(claudishSkillDir, { recursive: true });
|
|
44599
44704
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
44600
44705
|
}
|
|
@@ -44637,9 +44742,9 @@ function printAvailableModels() {
|
|
|
44637
44742
|
let lastUpdated = "unknown";
|
|
44638
44743
|
let models = [];
|
|
44639
44744
|
try {
|
|
44640
|
-
const cachePath =
|
|
44641
|
-
if (
|
|
44642
|
-
const data = JSON.parse(
|
|
44745
|
+
const cachePath = existsSync22(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
44746
|
+
if (existsSync22(cachePath)) {
|
|
44747
|
+
const data = JSON.parse(readFileSync20(cachePath, "utf-8"));
|
|
44643
44748
|
lastUpdated = data.lastUpdated || "unknown";
|
|
44644
44749
|
models = data.models || [];
|
|
44645
44750
|
}
|
|
@@ -44688,9 +44793,9 @@ Force update: claudish --list-models --force-update
|
|
|
44688
44793
|
`);
|
|
44689
44794
|
}
|
|
44690
44795
|
function printAvailableModelsJSON() {
|
|
44691
|
-
const jsonPath =
|
|
44796
|
+
const jsonPath = existsSync22(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
44692
44797
|
try {
|
|
44693
|
-
const jsonContent =
|
|
44798
|
+
const jsonContent = readFileSync20(jsonPath, "utf-8");
|
|
44694
44799
|
const data = JSON.parse(jsonContent);
|
|
44695
44800
|
console.log(JSON.stringify(data, null, 2));
|
|
44696
44801
|
} catch (error2) {
|
|
@@ -44787,10 +44892,10 @@ var init_cli = __esm(() => {
|
|
|
44787
44892
|
init_provider_resolver();
|
|
44788
44893
|
__filename4 = fileURLToPath3(import.meta.url);
|
|
44789
44894
|
__dirname4 = dirname3(__filename4);
|
|
44790
|
-
CLAUDISH_CACHE_DIR2 =
|
|
44791
|
-
BUNDLED_MODELS_PATH =
|
|
44792
|
-
CACHED_MODELS_PATH =
|
|
44793
|
-
ALL_MODELS_JSON_PATH =
|
|
44895
|
+
CLAUDISH_CACHE_DIR2 = join24(homedir23(), ".claudish");
|
|
44896
|
+
BUNDLED_MODELS_PATH = join24(__dirname4, "../recommended-models.json");
|
|
44897
|
+
CACHED_MODELS_PATH = join24(CLAUDISH_CACHE_DIR2, "recommended-models.json");
|
|
44898
|
+
ALL_MODELS_JSON_PATH = join24(CLAUDISH_CACHE_DIR2, "all-models.json");
|
|
44794
44899
|
});
|
|
44795
44900
|
|
|
44796
44901
|
// src/update-checker.ts
|
|
@@ -44801,33 +44906,33 @@ __export(exports_update_checker, {
|
|
|
44801
44906
|
clearCache: () => clearCache,
|
|
44802
44907
|
checkForUpdates: () => checkForUpdates
|
|
44803
44908
|
});
|
|
44804
|
-
import { existsSync as
|
|
44805
|
-
import { homedir as
|
|
44806
|
-
import { join as
|
|
44909
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync12, readFileSync as readFileSync21, unlinkSync as unlinkSync8, writeFileSync as writeFileSync13 } from "fs";
|
|
44910
|
+
import { homedir as homedir24, platform as platform2, tmpdir } from "os";
|
|
44911
|
+
import { join as join25 } from "path";
|
|
44807
44912
|
function getCacheFilePath() {
|
|
44808
44913
|
let cacheDir;
|
|
44809
44914
|
if (isWindows) {
|
|
44810
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
44811
|
-
cacheDir =
|
|
44915
|
+
const localAppData = process.env.LOCALAPPDATA || join25(homedir24(), "AppData", "Local");
|
|
44916
|
+
cacheDir = join25(localAppData, "claudish");
|
|
44812
44917
|
} else {
|
|
44813
|
-
cacheDir =
|
|
44918
|
+
cacheDir = join25(homedir24(), ".cache", "claudish");
|
|
44814
44919
|
}
|
|
44815
44920
|
try {
|
|
44816
|
-
if (!
|
|
44921
|
+
if (!existsSync23(cacheDir)) {
|
|
44817
44922
|
mkdirSync12(cacheDir, { recursive: true });
|
|
44818
44923
|
}
|
|
44819
|
-
return
|
|
44924
|
+
return join25(cacheDir, "update-check.json");
|
|
44820
44925
|
} catch {
|
|
44821
|
-
return
|
|
44926
|
+
return join25(tmpdir(), "claudish-update-check.json");
|
|
44822
44927
|
}
|
|
44823
44928
|
}
|
|
44824
44929
|
function readCache() {
|
|
44825
44930
|
try {
|
|
44826
44931
|
const cachePath = getCacheFilePath();
|
|
44827
|
-
if (!
|
|
44932
|
+
if (!existsSync23(cachePath)) {
|
|
44828
44933
|
return null;
|
|
44829
44934
|
}
|
|
44830
|
-
const data = JSON.parse(
|
|
44935
|
+
const data = JSON.parse(readFileSync21(cachePath, "utf-8"));
|
|
44831
44936
|
return data;
|
|
44832
44937
|
} catch {
|
|
44833
44938
|
return null;
|
|
@@ -44850,7 +44955,7 @@ function isCacheValid(cache) {
|
|
|
44850
44955
|
function clearCache() {
|
|
44851
44956
|
try {
|
|
44852
44957
|
const cachePath = getCacheFilePath();
|
|
44853
|
-
if (
|
|
44958
|
+
if (existsSync23(cachePath)) {
|
|
44854
44959
|
unlinkSync8(cachePath);
|
|
44855
44960
|
}
|
|
44856
44961
|
} catch {}
|
|
@@ -45151,15 +45256,15 @@ __export(exports_model_selector, {
|
|
|
45151
45256
|
promptForApiKey: () => promptForApiKey,
|
|
45152
45257
|
confirmAction: () => confirmAction
|
|
45153
45258
|
});
|
|
45154
|
-
import { readFileSync as
|
|
45155
|
-
import { join as
|
|
45156
|
-
import { homedir as
|
|
45259
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync14, existsSync as existsSync24, mkdirSync as mkdirSync13 } from "fs";
|
|
45260
|
+
import { join as join26, dirname as dirname4 } from "path";
|
|
45261
|
+
import { homedir as homedir25 } from "os";
|
|
45157
45262
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
45158
45263
|
function loadRecommendedModels2() {
|
|
45159
|
-
const cachedPath =
|
|
45160
|
-
if (
|
|
45264
|
+
const cachedPath = join26(CLAUDISH_CACHE_DIR3, "recommended-models-cache.json");
|
|
45265
|
+
if (existsSync24(cachedPath)) {
|
|
45161
45266
|
try {
|
|
45162
|
-
const data = JSON.parse(
|
|
45267
|
+
const data = JSON.parse(readFileSync22(cachedPath, "utf-8"));
|
|
45163
45268
|
if (data.models && data.models.length > 0) {
|
|
45164
45269
|
return data.models.map((model) => ({
|
|
45165
45270
|
...model,
|
|
@@ -45168,9 +45273,9 @@ function loadRecommendedModels2() {
|
|
|
45168
45273
|
}
|
|
45169
45274
|
} catch {}
|
|
45170
45275
|
}
|
|
45171
|
-
if (
|
|
45276
|
+
if (existsSync24(RECOMMENDED_MODELS_JSON_PATH)) {
|
|
45172
45277
|
try {
|
|
45173
|
-
const content =
|
|
45278
|
+
const content = readFileSync22(RECOMMENDED_MODELS_JSON_PATH, "utf-8");
|
|
45174
45279
|
const data = JSON.parse(content);
|
|
45175
45280
|
return (data.models || []).map((model) => ({
|
|
45176
45281
|
...model,
|
|
@@ -45183,9 +45288,9 @@ function loadRecommendedModels2() {
|
|
|
45183
45288
|
return [];
|
|
45184
45289
|
}
|
|
45185
45290
|
async function fetchAllModels(forceUpdate = false) {
|
|
45186
|
-
if (!forceUpdate &&
|
|
45291
|
+
if (!forceUpdate && existsSync24(ALL_MODELS_JSON_PATH2)) {
|
|
45187
45292
|
try {
|
|
45188
|
-
const cacheData = JSON.parse(
|
|
45293
|
+
const cacheData = JSON.parse(readFileSync22(ALL_MODELS_JSON_PATH2, "utf-8"));
|
|
45189
45294
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
45190
45295
|
const now = new Date;
|
|
45191
45296
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -45687,11 +45792,11 @@ async function fetchOllamaCloudModels() {
|
|
|
45687
45792
|
}
|
|
45688
45793
|
}
|
|
45689
45794
|
function shouldRefreshForFreeModels() {
|
|
45690
|
-
if (!
|
|
45795
|
+
if (!existsSync24(ALL_MODELS_JSON_PATH2)) {
|
|
45691
45796
|
return true;
|
|
45692
45797
|
}
|
|
45693
45798
|
try {
|
|
45694
|
-
const cacheData = JSON.parse(
|
|
45799
|
+
const cacheData = JSON.parse(readFileSync22(ALL_MODELS_JSON_PATH2, "utf-8"));
|
|
45695
45800
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
45696
45801
|
const now = new Date;
|
|
45697
45802
|
const ageInHours = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60);
|
|
@@ -46388,9 +46493,9 @@ var init_model_selector = __esm(() => {
|
|
|
46388
46493
|
init_provider_definitions();
|
|
46389
46494
|
__filename5 = fileURLToPath4(import.meta.url);
|
|
46390
46495
|
__dirname5 = dirname4(__filename5);
|
|
46391
|
-
CLAUDISH_CACHE_DIR3 =
|
|
46392
|
-
ALL_MODELS_JSON_PATH2 =
|
|
46393
|
-
RECOMMENDED_MODELS_JSON_PATH =
|
|
46496
|
+
CLAUDISH_CACHE_DIR3 = join26(homedir25(), ".claudish");
|
|
46497
|
+
ALL_MODELS_JSON_PATH2 = join26(CLAUDISH_CACHE_DIR3, "all-models.json");
|
|
46498
|
+
RECOMMENDED_MODELS_JSON_PATH = join26(__dirname5, "../recommended-models.json");
|
|
46394
46499
|
PROVIDER_FILTER_ALIASES = {
|
|
46395
46500
|
zen: "Zen",
|
|
46396
46501
|
openrouter: "OpenRouter",
|
|
@@ -47076,13 +47181,13 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
47076
47181
|
import { resolve as resolve3, dirname as dirname5 } from "path";
|
|
47077
47182
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
47078
47183
|
import { resolve as resolve22, isAbsolute, parse as parse6 } from "path";
|
|
47079
|
-
import { existsSync as
|
|
47080
|
-
import { basename, join as
|
|
47184
|
+
import { existsSync as existsSync25 } from "fs";
|
|
47185
|
+
import { basename, join as join27 } from "path";
|
|
47081
47186
|
import os2 from "os";
|
|
47082
47187
|
import path2 from "path";
|
|
47083
47188
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
47084
47189
|
import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr4 } from "bun:ffi";
|
|
47085
|
-
import { existsSync as
|
|
47190
|
+
import { existsSync as existsSync26, writeFileSync as writeFileSync15 } from "fs";
|
|
47086
47191
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
47087
47192
|
import { toArrayBuffer, ptr } from "bun:ffi";
|
|
47088
47193
|
import { ptr as ptr2, toArrayBuffer as toArrayBuffer2 } from "bun:ffi";
|
|
@@ -49476,7 +49581,7 @@ function getBunfsRootPath() {
|
|
|
49476
49581
|
return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
|
|
49477
49582
|
}
|
|
49478
49583
|
function normalizeBunfsPath(fileName) {
|
|
49479
|
-
return
|
|
49584
|
+
return join27(getBunfsRootPath(), basename(fileName));
|
|
49480
49585
|
}
|
|
49481
49586
|
function isValidDirectoryName(name) {
|
|
49482
49587
|
if (!name || typeof name !== "string") {
|
|
@@ -59672,7 +59777,7 @@ var init_index_0wbvecnk = __esm(async () => {
|
|
|
59672
59777
|
worker_path = this.options.workerPath;
|
|
59673
59778
|
} else {
|
|
59674
59779
|
worker_path = new URL("./parser.worker.js", import.meta.url).href;
|
|
59675
|
-
if (!
|
|
59780
|
+
if (!existsSync25(resolve22(import.meta.dirname, "parser.worker.js"))) {
|
|
59676
59781
|
worker_path = new URL("./parser.worker.ts", import.meta.url).href;
|
|
59677
59782
|
}
|
|
59678
59783
|
}
|
|
@@ -60373,7 +60478,7 @@ var init_index_0wbvecnk = __esm(async () => {
|
|
|
60373
60478
|
if (isBunfsPath(targetLibPath)) {
|
|
60374
60479
|
targetLibPath = targetLibPath.replace("../", "");
|
|
60375
60480
|
}
|
|
60376
|
-
if (!
|
|
60481
|
+
if (!existsSync26(targetLibPath)) {
|
|
60377
60482
|
throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
|
|
60378
60483
|
}
|
|
60379
60484
|
registerEnvVar({
|
|
@@ -105992,9 +106097,9 @@ __export(exports_claude_runner, {
|
|
|
105992
106097
|
checkClaudeInstalled: () => checkClaudeInstalled
|
|
105993
106098
|
});
|
|
105994
106099
|
import { spawn as spawn4 } from "child_process";
|
|
105995
|
-
import { writeFileSync as writeFileSync16, unlinkSync as unlinkSync9, mkdirSync as mkdirSync14, existsSync as
|
|
105996
|
-
import { tmpdir as tmpdir2, homedir as
|
|
105997
|
-
import { join as
|
|
106100
|
+
import { writeFileSync as writeFileSync16, unlinkSync as unlinkSync9, mkdirSync as mkdirSync14, existsSync as existsSync27, readFileSync as readFileSync23 } from "fs";
|
|
106101
|
+
import { tmpdir as tmpdir2, homedir as homedir26 } from "os";
|
|
106102
|
+
import { join as join28 } from "path";
|
|
105998
106103
|
function hasNativeAnthropicMapping(config3) {
|
|
105999
106104
|
const models = [
|
|
106000
106105
|
config3.model,
|
|
@@ -106010,9 +106115,9 @@ function isWindows2() {
|
|
|
106010
106115
|
}
|
|
106011
106116
|
function createStatusLineScript(tokenFilePath) {
|
|
106012
106117
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
106013
|
-
const claudishDir =
|
|
106118
|
+
const claudishDir = join28(homeDir, ".claudish");
|
|
106014
106119
|
const timestamp = Date.now();
|
|
106015
|
-
const scriptPath =
|
|
106120
|
+
const scriptPath = join28(claudishDir, `status-${timestamp}.js`);
|
|
106016
106121
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
106017
106122
|
const script = `
|
|
106018
106123
|
const fs = require('fs');
|
|
@@ -106050,9 +106155,9 @@ process.stdin.on('end', () => {
|
|
|
106050
106155
|
try {
|
|
106051
106156
|
const tokens = JSON.parse(fs.readFileSync('${escapedTokenPath}', 'utf-8'));
|
|
106052
106157
|
cost = tokens.total_cost || 0;
|
|
106053
|
-
ctx = tokens.context_left_percent
|
|
106158
|
+
ctx = tokens.context_left_percent ?? -1;
|
|
106054
106159
|
inputTokens = tokens.input_tokens || 0;
|
|
106055
|
-
contextWindow = tokens.context_window
|
|
106160
|
+
contextWindow = typeof tokens.context_window === 'number' ? tokens.context_window : 0;
|
|
106056
106161
|
isFree = tokens.is_free || false;
|
|
106057
106162
|
isEstimated = tokens.is_estimated || false;
|
|
106058
106163
|
providerName = tokens.provider_name || '';
|
|
@@ -106078,7 +106183,10 @@ process.stdin.on('end', () => {
|
|
|
106078
106183
|
const modelDisplay = providerName ? providerName + ' ' + model : model;
|
|
106079
106184
|
// Format context display as progress bar: [\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591] 116k/1M
|
|
106080
106185
|
let ctxDisplay = '';
|
|
106081
|
-
if (
|
|
106186
|
+
if (ctx < 0 || contextWindow <= 0) {
|
|
106187
|
+
// Unknown context window \u2014 show token count only
|
|
106188
|
+
ctxDisplay = inputTokens > 0 ? formatTokens(inputTokens) + ' tokens' : 'N/A';
|
|
106189
|
+
} else if (inputTokens > 0 && contextWindow > 0) {
|
|
106082
106190
|
const usedPct = 100 - ctx; // ctx is "left", so used = 100 - left
|
|
106083
106191
|
const barWidth = 15;
|
|
106084
106192
|
const filled = Math.round((usedPct / 100) * barWidth);
|
|
@@ -106106,13 +106214,13 @@ process.stdin.on('end', () => {
|
|
|
106106
106214
|
}
|
|
106107
106215
|
function createTempSettingsFile(modelDisplay, port) {
|
|
106108
106216
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
106109
|
-
const claudishDir =
|
|
106217
|
+
const claudishDir = join28(homeDir, ".claudish");
|
|
106110
106218
|
try {
|
|
106111
106219
|
mkdirSync14(claudishDir, { recursive: true });
|
|
106112
106220
|
} catch {}
|
|
106113
106221
|
const timestamp = Date.now();
|
|
106114
|
-
const tempPath =
|
|
106115
|
-
const tokenFilePath =
|
|
106222
|
+
const tempPath = join28(claudishDir, `settings-${timestamp}.json`);
|
|
106223
|
+
const tokenFilePath = join28(claudishDir, `tokens-${port}.json`);
|
|
106116
106224
|
let statusCommand;
|
|
106117
106225
|
if (isWindows2()) {
|
|
106118
106226
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -106126,7 +106234,7 @@ function createTempSettingsFile(modelDisplay, port) {
|
|
|
106126
106234
|
const RESET4 = "\\033[0m";
|
|
106127
106235
|
const BOLD4 = "\\033[1m";
|
|
106128
106236
|
const formatTokensBash = `fmt_tok() { local n=\${1:-0}; if [ "$n" -ge 1000000 ]; then echo "$((n/1000000))M"; elif [ "$n" -ge 1000 ]; then echo "$((n/1000))k"; else echo "$n"; fi; }`;
|
|
106129
|
-
statusCommand = `JSON=$(cat) && DIR=$(basename "$(pwd)") && [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true && CTX
|
|
106237
|
+
statusCommand = `JSON=$(cat) && DIR=$(basename "$(pwd)") && [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true && CTX=-1 && COST="0" && IS_FREE="false" && IS_EST="false" && PROVIDER="" && TOKEN_MODEL="" && IN_TOK=0 && CTX_WIN=0 && ${formatTokensBash} && if [ -f "${tokenFilePath}" ]; then TOKENS=$(cat "${tokenFilePath}" 2>/dev/null | tr -d ' \\n') && REAL_CTX=$(echo "$TOKENS" | grep -o '"context_left_percent":-\\?[0-9]*' | grep -o '\\-\\?[0-9]*') && if [ ! -z "$REAL_CTX" ]; then CTX="$REAL_CTX"; fi && REAL_COST=$(echo "$TOKENS" | grep -o '"total_cost":[0-9.]*' | cut -d: -f2) && if [ ! -z "$REAL_COST" ]; then COST="$REAL_COST"; fi && IN_TOK=$(echo "$TOKENS" | grep -o '"input_tokens":[0-9]*' | grep -o '[0-9]*') && CTX_WIN=$(echo "$TOKENS" | grep -o '"context_window":[0-9]*' | grep -o '[0-9]*') && IS_FREE=$(echo "$TOKENS" | grep -o '"is_free":[a-z]*' | cut -d: -f2) && IS_EST=$(echo "$TOKENS" | grep -o '"is_estimated":[a-z]*' | cut -d: -f2) && PROVIDER=$(echo "$TOKENS" | grep -o '"provider_name":"[^"]*"' | cut -d'"' -f4) && TOKEN_MODEL=$(echo "$TOKENS" | grep -o '"model_name":"[^"]*"' | cut -d'"' -f4); fi && if [ "$CLAUDISH_IS_LOCAL" = "true" ]; then COST_DISPLAY="LOCAL"; elif [ "$IS_FREE" = "true" ]; then COST_DISPLAY="FREE"; elif [ "$IS_EST" = "true" ]; then COST_DISPLAY=$(printf "~\\$%.3f" "$COST"); else COST_DISPLAY=$(printf "\\$%.3f" "$COST"); fi && MODEL_DISPLAY="\${TOKEN_MODEL:-$CLAUDISH_ACTIVE_MODEL_NAME}" && if [ ! -z "$PROVIDER" ]; then MODEL_DISPLAY="$PROVIDER $MODEL_DISPLAY"; fi && if [ "$CTX" -lt 0 ] 2>/dev/null || [ "$CTX_WIN" -le 0 ] 2>/dev/null; then if [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$(fmt_tok $IN_TOK) tokens"; else CTX_DISPLAY="N/A"; fi; elif [ "$IN_TOK" -gt 0 ] 2>/dev/null && [ "$CTX_WIN" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $CTX_WIN))"; else CTX_DISPLAY="$CTX%"; fi && printf "${CYAN4}${BOLD4}%s${RESET4} ${DIM4}\u2022${RESET4} ${YELLOW3}%s${RESET4} ${DIM4}\u2022${RESET4} ${GREEN4}%s${RESET4} ${DIM4}\u2022${RESET4} ${MAGENTA3}%s${RESET4}\\n" "$DIR" "$MODEL_DISPLAY" "$COST_DISPLAY" "$CTX_DISPLAY"`;
|
|
106130
106238
|
}
|
|
106131
106239
|
const statusLine = {
|
|
106132
106240
|
type: "command",
|
|
@@ -106148,7 +106256,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
|
106148
106256
|
if (userSettingsValue.trimStart().startsWith("{")) {
|
|
106149
106257
|
userSettings = JSON.parse(userSettingsValue);
|
|
106150
106258
|
} else {
|
|
106151
|
-
const rawUserSettings =
|
|
106259
|
+
const rawUserSettings = readFileSync23(userSettingsValue, "utf-8");
|
|
106152
106260
|
userSettings = JSON.parse(rawUserSettings);
|
|
106153
106261
|
}
|
|
106154
106262
|
userSettings.statusLine = statusLine;
|
|
@@ -106240,8 +106348,8 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
106240
106348
|
console.error("Install it from: https://claude.com/claude-code");
|
|
106241
106349
|
console.error(`
|
|
106242
106350
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
106243
|
-
const home =
|
|
106244
|
-
const localPath = isWindows2() ?
|
|
106351
|
+
const home = homedir26();
|
|
106352
|
+
const localPath = isWindows2() ? join28(home, ".claude", "local", "claude.exe") : join28(home, ".claude", "local", "claude");
|
|
106245
106353
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
106246
106354
|
process.exit(1);
|
|
106247
106355
|
}
|
|
@@ -106287,23 +106395,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
106287
106395
|
async function findClaudeBinary() {
|
|
106288
106396
|
const isWindows3 = process.platform === "win32";
|
|
106289
106397
|
if (process.env.CLAUDE_PATH) {
|
|
106290
|
-
if (
|
|
106398
|
+
if (existsSync27(process.env.CLAUDE_PATH)) {
|
|
106291
106399
|
return process.env.CLAUDE_PATH;
|
|
106292
106400
|
}
|
|
106293
106401
|
}
|
|
106294
|
-
const home =
|
|
106295
|
-
const localPath = isWindows3 ?
|
|
106296
|
-
if (
|
|
106402
|
+
const home = homedir26();
|
|
106403
|
+
const localPath = isWindows3 ? join28(home, ".claude", "local", "claude.exe") : join28(home, ".claude", "local", "claude");
|
|
106404
|
+
if (existsSync27(localPath)) {
|
|
106297
106405
|
return localPath;
|
|
106298
106406
|
}
|
|
106299
106407
|
if (isWindows3) {
|
|
106300
106408
|
const windowsPaths = [
|
|
106301
|
-
|
|
106302
|
-
|
|
106303
|
-
|
|
106409
|
+
join28(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
106410
|
+
join28(home, ".npm-global", "claude.cmd"),
|
|
106411
|
+
join28(home, "node_modules", ".bin", "claude.cmd")
|
|
106304
106412
|
];
|
|
106305
106413
|
for (const path3 of windowsPaths) {
|
|
106306
|
-
if (
|
|
106414
|
+
if (existsSync27(path3)) {
|
|
106307
106415
|
return path3;
|
|
106308
106416
|
}
|
|
106309
106417
|
}
|
|
@@ -106311,14 +106419,14 @@ async function findClaudeBinary() {
|
|
|
106311
106419
|
const commonPaths = [
|
|
106312
106420
|
"/usr/local/bin/claude",
|
|
106313
106421
|
"/opt/homebrew/bin/claude",
|
|
106314
|
-
|
|
106315
|
-
|
|
106316
|
-
|
|
106422
|
+
join28(home, ".npm-global/bin/claude"),
|
|
106423
|
+
join28(home, ".local/bin/claude"),
|
|
106424
|
+
join28(home, "node_modules/.bin/claude"),
|
|
106317
106425
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
106318
|
-
|
|
106426
|
+
join28(home, "../usr/bin/claude")
|
|
106319
106427
|
];
|
|
106320
106428
|
for (const path3 of commonPaths) {
|
|
106321
|
-
if (
|
|
106429
|
+
if (existsSync27(path3)) {
|
|
106322
106430
|
return path3;
|
|
106323
106431
|
}
|
|
106324
106432
|
}
|
|
@@ -106368,17 +106476,17 @@ __export(exports_diag_output, {
|
|
|
106368
106476
|
LogFileDiagOutput: () => LogFileDiagOutput
|
|
106369
106477
|
});
|
|
106370
106478
|
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17, unlinkSync as unlinkSync10 } from "fs";
|
|
106371
|
-
import { homedir as
|
|
106372
|
-
import { join as
|
|
106479
|
+
import { homedir as homedir27 } from "os";
|
|
106480
|
+
import { join as join29 } from "path";
|
|
106373
106481
|
function getClaudishDir() {
|
|
106374
|
-
const dir =
|
|
106482
|
+
const dir = join29(homedir27(), ".claudish");
|
|
106375
106483
|
try {
|
|
106376
106484
|
mkdirSync15(dir, { recursive: true });
|
|
106377
106485
|
} catch {}
|
|
106378
106486
|
return dir;
|
|
106379
106487
|
}
|
|
106380
106488
|
function getDiagLogPath() {
|
|
106381
|
-
return
|
|
106489
|
+
return join29(getClaudishDir(), `diag-${process.pid}.log`);
|
|
106382
106490
|
}
|
|
106383
106491
|
|
|
106384
106492
|
class LogFileDiagOutput {
|
|
@@ -106437,42 +106545,112 @@ __export(exports_team_grid, {
|
|
|
106437
106545
|
});
|
|
106438
106546
|
import { spawn as spawn5 } from "child_process";
|
|
106439
106547
|
import {
|
|
106440
|
-
|
|
106441
|
-
existsSync as existsSync28,
|
|
106548
|
+
existsSync as existsSync29,
|
|
106442
106549
|
mkdirSync as mkdirSync16,
|
|
106443
|
-
readFileSync as
|
|
106550
|
+
readFileSync as readFileSync24,
|
|
106444
106551
|
unlinkSync as unlinkSync11,
|
|
106445
106552
|
writeFileSync as writeFileSync18
|
|
106446
106553
|
} from "fs";
|
|
106447
|
-
import { dirname as dirname6, join as
|
|
106554
|
+
import { dirname as dirname6, join as join30 } from "path";
|
|
106448
106555
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
106449
106556
|
import { execSync as execSync2 } from "child_process";
|
|
106450
|
-
function
|
|
106451
|
-
const
|
|
106452
|
-
if (
|
|
106453
|
-
return
|
|
106454
|
-
|
|
106455
|
-
const
|
|
106456
|
-
|
|
106557
|
+
function resolveRouteInfo(modelId) {
|
|
106558
|
+
const parsed = parseModelSpec(modelId);
|
|
106559
|
+
if (parsed.isExplicitProvider) {
|
|
106560
|
+
return { chain: [parsed.provider], source: "direct" };
|
|
106561
|
+
}
|
|
106562
|
+
const local = loadLocalConfig();
|
|
106563
|
+
if (local?.routing && Object.keys(local.routing).length > 0) {
|
|
106564
|
+
const matched = matchRoutingRule(parsed.model, local.routing);
|
|
106565
|
+
if (matched) {
|
|
106566
|
+
const routes2 = buildRoutingChain(matched, parsed.model);
|
|
106567
|
+
const pattern = Object.keys(local.routing).find((k2) => {
|
|
106568
|
+
if (k2 === parsed.model)
|
|
106569
|
+
return true;
|
|
106570
|
+
if (k2.includes("*")) {
|
|
106571
|
+
const star = k2.indexOf("*");
|
|
106572
|
+
return parsed.model.startsWith(k2.slice(0, star)) && parsed.model.endsWith(k2.slice(star + 1));
|
|
106573
|
+
}
|
|
106574
|
+
return false;
|
|
106575
|
+
});
|
|
106576
|
+
return {
|
|
106577
|
+
chain: routes2.map((r) => r.displayName),
|
|
106578
|
+
source: "project routing",
|
|
106579
|
+
sourceDetail: pattern
|
|
106580
|
+
};
|
|
106581
|
+
}
|
|
106582
|
+
}
|
|
106583
|
+
const global_ = loadConfig();
|
|
106584
|
+
if (global_.routing && Object.keys(global_.routing).length > 0) {
|
|
106585
|
+
const matched = matchRoutingRule(parsed.model, global_.routing);
|
|
106586
|
+
if (matched) {
|
|
106587
|
+
const routes2 = buildRoutingChain(matched, parsed.model);
|
|
106588
|
+
const pattern = Object.keys(global_.routing).find((k2) => {
|
|
106589
|
+
if (k2 === parsed.model)
|
|
106590
|
+
return true;
|
|
106591
|
+
if (k2.includes("*")) {
|
|
106592
|
+
const star = k2.indexOf("*");
|
|
106593
|
+
return parsed.model.startsWith(k2.slice(0, star)) && parsed.model.endsWith(k2.slice(star + 1));
|
|
106594
|
+
}
|
|
106595
|
+
return false;
|
|
106596
|
+
});
|
|
106597
|
+
return {
|
|
106598
|
+
chain: routes2.map((r) => r.displayName),
|
|
106599
|
+
source: "user routing",
|
|
106600
|
+
sourceDetail: pattern
|
|
106601
|
+
};
|
|
106602
|
+
}
|
|
106603
|
+
}
|
|
106604
|
+
const routes = getFallbackChain(parsed.model, parsed.provider);
|
|
106605
|
+
return {
|
|
106606
|
+
chain: routes.map((r) => r.displayName),
|
|
106607
|
+
source: "auto"
|
|
106608
|
+
};
|
|
106609
|
+
}
|
|
106610
|
+
function buildPaneHeader(model, prompt) {
|
|
106611
|
+
const route = resolveRouteInfo(model);
|
|
106612
|
+
const esc2 = (s) => s.replace(/'/g, "'\\''");
|
|
106613
|
+
const bgColors = [
|
|
106614
|
+
"48;2;40;90;180",
|
|
106615
|
+
"48;2;140;60;160",
|
|
106616
|
+
"48;2;30;130;100",
|
|
106617
|
+
"48;2;160;80;40",
|
|
106618
|
+
"48;2;60;120;60",
|
|
106619
|
+
"48;2;160;50;70"
|
|
106620
|
+
];
|
|
106621
|
+
let hash = 0;
|
|
106622
|
+
for (let i = 0;i < model.length; i++)
|
|
106623
|
+
hash = (hash << 5) - hash + model.charCodeAt(i) | 0;
|
|
106624
|
+
const bg2 = bgColors[Math.abs(hash) % bgColors.length];
|
|
106625
|
+
const chainStr = route.chain.join(" \u2192 ");
|
|
106626
|
+
const sourceLabel = route.sourceDetail ? `${route.source}: ${route.sourceDetail}` : route.source;
|
|
106627
|
+
const lines = [];
|
|
106628
|
+
lines.push(`printf '\\033[1;97;${bg2}m %s \\033[0m\\n' '${esc2(model)}';`);
|
|
106629
|
+
lines.push(`printf '\\033[2m route: ${esc2(chainStr)} (${esc2(sourceLabel)})\\033[0m\\n' ;`);
|
|
106630
|
+
lines.push(`printf '\\033[2m %s\\033[0m\\n' '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';`);
|
|
106631
|
+
const promptForShell = esc2(prompt).replace(/\n/g, "\\n");
|
|
106632
|
+
lines.push(`printf '%b\\n' '${promptForShell}' | fold -s -w 78 | sed 's/^/ /';`);
|
|
106633
|
+
lines.push(`printf '\\033[2m %s\\033[0m\\n\\n' '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';`);
|
|
106634
|
+
return lines.join(" ");
|
|
106457
106635
|
}
|
|
106458
106636
|
function findMagmuxBinary() {
|
|
106459
106637
|
const thisFile = fileURLToPath6(import.meta.url);
|
|
106460
106638
|
const thisDir = dirname6(thisFile);
|
|
106461
|
-
const pkgRoot =
|
|
106639
|
+
const pkgRoot = join30(thisDir, "..");
|
|
106462
106640
|
const platform3 = process.platform;
|
|
106463
106641
|
const arch = process.arch;
|
|
106464
|
-
const builtMagmux =
|
|
106465
|
-
if (
|
|
106642
|
+
const builtMagmux = join30(pkgRoot, "native", "magmux", "magmux");
|
|
106643
|
+
if (existsSync29(builtMagmux))
|
|
106466
106644
|
return builtMagmux;
|
|
106467
|
-
const bundledMagmux =
|
|
106468
|
-
if (
|
|
106645
|
+
const bundledMagmux = join30(pkgRoot, "native", "magmux", `magmux-${platform3}-${arch}`);
|
|
106646
|
+
if (existsSync29(bundledMagmux))
|
|
106469
106647
|
return bundledMagmux;
|
|
106470
106648
|
try {
|
|
106471
106649
|
const pkgName = `@claudish/magmux-${platform3}-${arch}`;
|
|
106472
106650
|
let searchDir = pkgRoot;
|
|
106473
106651
|
for (let i = 0;i < 5; i++) {
|
|
106474
|
-
const candidate =
|
|
106475
|
-
if (
|
|
106652
|
+
const candidate = join30(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
106653
|
+
if (existsSync29(candidate))
|
|
106476
106654
|
return candidate;
|
|
106477
106655
|
const parent = dirname6(searchDir);
|
|
106478
106656
|
if (parent === searchDir)
|
|
@@ -106488,141 +106666,97 @@ function findMagmuxBinary() {
|
|
|
106488
106666
|
throw new Error(`magmux not found. Install it:
|
|
106489
106667
|
brew install MadAppGang/tap/magmux`);
|
|
106490
106668
|
}
|
|
106491
|
-
function
|
|
106492
|
-
const
|
|
106493
|
-
const { done, running, failed, total, allDone } = counts;
|
|
106494
|
-
if (allDone) {
|
|
106495
|
-
if (failed > 0) {
|
|
106496
|
-
return [
|
|
106497
|
-
"C: claudish team",
|
|
106498
|
-
`G: ${done} done`,
|
|
106499
|
-
`R: ${failed} failed`,
|
|
106500
|
-
`D: ${elapsed}`,
|
|
106501
|
-
"R: \u2717 issues",
|
|
106502
|
-
"D: ctrl-g q to quit"
|
|
106503
|
-
].join("\t");
|
|
106504
|
-
}
|
|
106505
|
-
return [
|
|
106506
|
-
"C: claudish team",
|
|
106507
|
-
`G: ${total} done`,
|
|
106508
|
-
`D: ${elapsed}`,
|
|
106509
|
-
"G: \u2713 complete",
|
|
106510
|
-
"D: ctrl-g q to quit"
|
|
106511
|
-
].join("\t");
|
|
106512
|
-
}
|
|
106513
|
-
return [
|
|
106514
|
-
"C: claudish team",
|
|
106515
|
-
`G: ${done} done`,
|
|
106516
|
-
`C: ${running} running`,
|
|
106517
|
-
`R: ${failed} failed`,
|
|
106518
|
-
`D: ${elapsed}`
|
|
106519
|
-
].join("\t");
|
|
106520
|
-
}
|
|
106521
|
-
function pollStatus(state) {
|
|
106522
|
-
const { statusCache, statusPath, sessionPath, anonIds, startTime, timeoutMs, statusbarPath } = state;
|
|
106523
|
-
const elapsedMs = Date.now() - startTime;
|
|
106524
|
-
let changed = false;
|
|
106525
|
-
let done = 0;
|
|
106526
|
-
let running = 0;
|
|
106527
|
-
let failed = 0;
|
|
106669
|
+
function finalizeStatus(statusPath, sessionPath, anonIds) {
|
|
106670
|
+
const statusCache = JSON.parse(readFileSync24(statusPath, "utf-8"));
|
|
106528
106671
|
for (const anonId of anonIds) {
|
|
106529
106672
|
const current = statusCache.models[anonId];
|
|
106530
|
-
if (current.state === "COMPLETED" || current.state === "FAILED"
|
|
106531
|
-
if (current.state === "COMPLETED")
|
|
106532
|
-
done++;
|
|
106533
|
-
else
|
|
106534
|
-
failed++;
|
|
106673
|
+
if (current.state === "COMPLETED" || current.state === "FAILED")
|
|
106535
106674
|
continue;
|
|
106536
|
-
|
|
106537
|
-
|
|
106538
|
-
|
|
106539
|
-
|
|
106540
|
-
const code = parseInt(codeStr, 10);
|
|
106541
|
-
const isSuccess = code === 0;
|
|
106542
|
-
const newState = {
|
|
106675
|
+
const exitCodePath = join30(sessionPath, "work", anonId, ".exit-code");
|
|
106676
|
+
if (existsSync29(exitCodePath)) {
|
|
106677
|
+
const code = parseInt(readFileSync24(exitCodePath, "utf-8").trim(), 10);
|
|
106678
|
+
statusCache.models[anonId] = {
|
|
106543
106679
|
...current,
|
|
106544
|
-
state:
|
|
106680
|
+
state: code === 0 ? "COMPLETED" : "FAILED",
|
|
106545
106681
|
exitCode: code,
|
|
106546
|
-
startedAt: current.startedAt ??
|
|
106547
|
-
completedAt: new Date().toISOString()
|
|
106548
|
-
outputSize: 0
|
|
106682
|
+
startedAt: current.startedAt ?? statusCache.startedAt,
|
|
106683
|
+
completedAt: new Date().toISOString()
|
|
106549
106684
|
};
|
|
106550
|
-
statusCache.models[anonId] = newState;
|
|
106551
|
-
changed = true;
|
|
106552
|
-
if (isSuccess)
|
|
106553
|
-
done++;
|
|
106554
|
-
else
|
|
106555
|
-
failed++;
|
|
106556
106685
|
} else {
|
|
106557
|
-
|
|
106558
|
-
const newState = {
|
|
106559
|
-
...current,
|
|
106560
|
-
state: "TIMEOUT",
|
|
106561
|
-
startedAt: current.startedAt ?? new Date().toISOString(),
|
|
106562
|
-
completedAt: new Date().toISOString(),
|
|
106563
|
-
outputSize: 0
|
|
106564
|
-
};
|
|
106565
|
-
statusCache.models[anonId] = newState;
|
|
106566
|
-
changed = true;
|
|
106567
|
-
failed++;
|
|
106568
|
-
} else {
|
|
106569
|
-
if (current.state === "PENDING" && elapsedMs > 1000) {
|
|
106570
|
-
statusCache.models[anonId] = {
|
|
106571
|
-
...current,
|
|
106572
|
-
state: "RUNNING",
|
|
106573
|
-
startedAt: current.startedAt ?? new Date().toISOString()
|
|
106574
|
-
};
|
|
106575
|
-
changed = true;
|
|
106576
|
-
}
|
|
106577
|
-
running++;
|
|
106578
|
-
}
|
|
106686
|
+
statusCache.models[anonId] = { ...current, state: "TIMEOUT" };
|
|
106579
106687
|
}
|
|
106580
106688
|
}
|
|
106581
|
-
|
|
106582
|
-
writeFileSync18(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
106583
|
-
}
|
|
106584
|
-
const total = anonIds.length;
|
|
106585
|
-
const allDone = done + failed >= total;
|
|
106586
|
-
if (allDone && !state.completedAtMs) {
|
|
106587
|
-
state.completedAtMs = elapsedMs;
|
|
106588
|
-
}
|
|
106589
|
-
const counts = {
|
|
106590
|
-
done,
|
|
106591
|
-
running,
|
|
106592
|
-
failed,
|
|
106593
|
-
total,
|
|
106594
|
-
elapsedMs: state.completedAtMs ?? elapsedMs,
|
|
106595
|
-
allDone
|
|
106596
|
-
};
|
|
106597
|
-
appendFileSync(statusbarPath, renderGridStatusBar(counts) + `
|
|
106598
|
-
`);
|
|
106599
|
-
return allDone;
|
|
106689
|
+
writeFileSync18(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
106600
106690
|
}
|
|
106601
106691
|
async function runWithGrid(sessionPath, models, input, opts) {
|
|
106602
|
-
const
|
|
106603
|
-
const
|
|
106692
|
+
const mode = opts?.mode ?? "default";
|
|
106693
|
+
const keep = opts?.keep ?? false;
|
|
106604
106694
|
const manifest = setupSession(sessionPath, models, input);
|
|
106605
|
-
mkdirSync16(
|
|
106695
|
+
mkdirSync16(join30(sessionPath, "errors"), { recursive: true });
|
|
106606
106696
|
for (const anonId of Object.keys(manifest.models)) {
|
|
106607
|
-
const stale =
|
|
106697
|
+
const stale = join30(sessionPath, "work", anonId, ".exit-code");
|
|
106608
106698
|
try {
|
|
106609
106699
|
unlinkSync11(stale);
|
|
106610
106700
|
} catch {}
|
|
106611
106701
|
}
|
|
106612
|
-
const gridfilePath =
|
|
106613
|
-
const prompt =
|
|
106702
|
+
const gridfilePath = join30(sessionPath, "gridfile.txt");
|
|
106703
|
+
const prompt = readFileSync24(join30(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
106704
|
+
const totalPanes = Object.keys(manifest.models).length;
|
|
106705
|
+
const workDir = join30(sessionPath, "work");
|
|
106706
|
+
const statusFunc = [
|
|
106707
|
+
`_update_bar() {`,
|
|
106708
|
+
`_d=0; _f=0;`,
|
|
106709
|
+
`for _ecf in $(find ${workDir} -name .exit-code 2>/dev/null); do`,
|
|
106710
|
+
`_c=$(cat "$_ecf" 2>/dev/null);`,
|
|
106711
|
+
`if [ "$_c" = "0" ]; then _d=$((_d+1)); else _f=$((_f+1)); fi;`,
|
|
106712
|
+
`done;`,
|
|
106713
|
+
`_r=$((${totalPanes}-_d-_f));`,
|
|
106714
|
+
`_e=$SECONDS;`,
|
|
106715
|
+
`if [ $_e -ge 60 ]; then _ts="$((_e/60))m $((_e%60))s"; else _ts="\${_e}s"; fi;`,
|
|
106716
|
+
`if [ $_r -eq 0 ] && [ $_f -eq 0 ]; then`,
|
|
106717
|
+
`_t="C: claudish team G: ${totalPanes} done G: complete D: \${_ts} D: ctrl-g q to quit";`,
|
|
106718
|
+
`elif [ $_r -eq 0 ] && [ $_f -gt 0 ]; then`,
|
|
106719
|
+
`_t="C: claudish team G: \${_d} done R: \${_f} failed D: \${_ts} D: ctrl-g q to quit";`,
|
|
106720
|
+
`else`,
|
|
106721
|
+
`_t="C: claudish team G: \${_d} done C: \${_r} running R: \${_f} failed D: \${_ts}";`,
|
|
106722
|
+
`fi;`,
|
|
106723
|
+
`_j=$(printf '%s' "$_t" | sed 's/ /\\\\t/g');`,
|
|
106724
|
+
`printf '{"cmd":"status","text":"%s"}' "$_j" | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
106725
|
+
`};`
|
|
106726
|
+
].join(" ");
|
|
106727
|
+
const rawPrompt = readFileSync24(join30(sessionPath, "input.md"), "utf-8");
|
|
106614
106728
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
106615
|
-
const errorLog =
|
|
106616
|
-
const exitCodeFile =
|
|
106729
|
+
const errorLog = join30(sessionPath, "errors", `${anonId}.log`);
|
|
106730
|
+
const exitCodeFile = join30(sessionPath, "work", anonId, ".exit-code");
|
|
106617
106731
|
const model = manifest.models[anonId].model;
|
|
106618
106732
|
const paneIndex = Object.keys(manifest.models).indexOf(anonId);
|
|
106619
|
-
if (interactive) {
|
|
106620
|
-
return
|
|
106621
|
-
|
|
106733
|
+
if (mode === "interactive") {
|
|
106734
|
+
return [
|
|
106735
|
+
`${statusFunc}`,
|
|
106736
|
+
`if [ -n "$MAGMUX_SOCK" ]; then _update_bar; fi;`,
|
|
106737
|
+
`claudish --model ${model} -i --dangerously-skip-permissions '${prompt}' 2>${errorLog};`,
|
|
106738
|
+
`_ec=$?; echo $_ec > ${exitCodeFile};`,
|
|
106739
|
+
`if [ -n "$MAGMUX_SOCK" ]; then`,
|
|
106740
|
+
` _update_bar;`,
|
|
106741
|
+
` if [ $_ec -eq 0 ]; then`,
|
|
106742
|
+
` echo '{"cmd":"tint","pane":${paneIndex},"color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
106743
|
+
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"DONE","color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
106744
|
+
` else`,
|
|
106745
|
+
` echo '{"cmd":"tint","pane":${paneIndex},"color":"red"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
106746
|
+
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"FAIL","color":"red"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
106747
|
+
` fi;`,
|
|
106748
|
+
`fi`
|
|
106749
|
+
].join(" ");
|
|
106750
|
+
}
|
|
106751
|
+
const header = buildPaneHeader(model, rawPrompt);
|
|
106622
106752
|
return [
|
|
106623
|
-
|
|
106753
|
+
`${statusFunc}`,
|
|
106754
|
+
`if [ -n "$MAGMUX_SOCK" ]; then _update_bar; fi;`,
|
|
106755
|
+
`${header}`,
|
|
106756
|
+
`claudish --model ${model} -y --quiet '${prompt}' 2>${errorLog};`,
|
|
106624
106757
|
`_ec=$?; echo $_ec > ${exitCodeFile};`,
|
|
106625
106758
|
`if [ -n "$MAGMUX_SOCK" ]; then`,
|
|
106759
|
+
` _update_bar;`,
|
|
106626
106760
|
` if [ $_ec -eq 0 ]; then`,
|
|
106627
106761
|
` echo '{"cmd":"tint","pane":${paneIndex},"color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
106628
106762
|
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"DONE","color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
@@ -106638,36 +106772,10 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
106638
106772
|
`) + `
|
|
106639
106773
|
`, "utf-8");
|
|
106640
106774
|
const magmuxPath = findMagmuxBinary();
|
|
106641
|
-
const
|
|
106642
|
-
const statusPath = join29(sessionPath, "status.json");
|
|
106643
|
-
const statusCache = JSON.parse(readFileSync23(statusPath, "utf-8"));
|
|
106775
|
+
const statusPath = join30(sessionPath, "status.json");
|
|
106644
106776
|
const anonIds = Object.keys(manifest.models);
|
|
106645
|
-
const
|
|
106646
|
-
|
|
106647
|
-
done: 0,
|
|
106648
|
-
running: 0,
|
|
106649
|
-
failed: 0,
|
|
106650
|
-
total: anonIds.length,
|
|
106651
|
-
elapsedMs: 0,
|
|
106652
|
-
allDone: false
|
|
106653
|
-
}) + `
|
|
106654
|
-
`);
|
|
106655
|
-
const pollState = {
|
|
106656
|
-
statusCache,
|
|
106657
|
-
statusPath,
|
|
106658
|
-
sessionPath,
|
|
106659
|
-
anonIds,
|
|
106660
|
-
startTime,
|
|
106661
|
-
timeoutMs,
|
|
106662
|
-
statusbarPath,
|
|
106663
|
-
completedAtMs: null,
|
|
106664
|
-
interactive
|
|
106665
|
-
};
|
|
106666
|
-
const pollInterval = setInterval(() => {
|
|
106667
|
-
pollStatus(pollState);
|
|
106668
|
-
}, 500);
|
|
106669
|
-
const spawnArgs = ["-g", gridfilePath, "-S", statusbarPath];
|
|
106670
|
-
if (!interactive) {
|
|
106777
|
+
const spawnArgs = ["-g", gridfilePath];
|
|
106778
|
+
if (!keep && mode === "default") {
|
|
106671
106779
|
spawnArgs.push("-w");
|
|
106672
106780
|
}
|
|
106673
106781
|
const proc = spawn5(magmuxPath, spawnArgs, {
|
|
@@ -106678,26 +106786,29 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
106678
106786
|
proc.on("exit", () => resolve4());
|
|
106679
106787
|
proc.on("error", () => resolve4());
|
|
106680
106788
|
});
|
|
106681
|
-
|
|
106682
|
-
|
|
106683
|
-
return JSON.parse(readFileSync23(statusPath, "utf-8"));
|
|
106789
|
+
finalizeStatus(statusPath, sessionPath, anonIds);
|
|
106790
|
+
return JSON.parse(readFileSync24(statusPath, "utf-8"));
|
|
106684
106791
|
}
|
|
106685
106792
|
var init_team_grid = __esm(() => {
|
|
106686
106793
|
init_team_orchestrator();
|
|
106794
|
+
init_model_parser();
|
|
106795
|
+
init_routing_rules();
|
|
106796
|
+
init_auto_route();
|
|
106797
|
+
init_profile_config();
|
|
106687
106798
|
});
|
|
106688
106799
|
|
|
106689
106800
|
// src/index.ts
|
|
106690
106801
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
106691
|
-
import { existsSync as
|
|
106692
|
-
import { homedir as
|
|
106693
|
-
import { join as
|
|
106802
|
+
import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
|
|
106803
|
+
import { homedir as homedir28 } from "os";
|
|
106804
|
+
import { join as join31 } from "path";
|
|
106694
106805
|
import_dotenv3.config({ quiet: true });
|
|
106695
106806
|
function loadStoredApiKeys() {
|
|
106696
106807
|
try {
|
|
106697
|
-
const configPath =
|
|
106698
|
-
if (!
|
|
106808
|
+
const configPath = join31(homedir28(), ".claudish", "config.json");
|
|
106809
|
+
if (!existsSync30(configPath))
|
|
106699
106810
|
return;
|
|
106700
|
-
const raw2 =
|
|
106811
|
+
const raw2 = readFileSync25(configPath, "utf-8");
|
|
106701
106812
|
const cfg = JSON.parse(raw2);
|
|
106702
106813
|
if (cfg.apiKeys) {
|
|
106703
106814
|
for (const [envVar, value] of Object.entries(cfg.apiKeys)) {
|
|
@@ -106811,14 +106922,14 @@ async function runCli() {
|
|
|
106811
106922
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
106812
106923
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
106813
106924
|
if (cliConfig.inputFile) {
|
|
106814
|
-
prompt =
|
|
106925
|
+
prompt = readFileSync25(cliConfig.inputFile, "utf-8");
|
|
106815
106926
|
}
|
|
106816
106927
|
if (!prompt.trim()) {
|
|
106817
106928
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
106818
106929
|
process.exit(1);
|
|
106819
106930
|
}
|
|
106820
106931
|
const mode = cliConfig.teamMode ?? "default";
|
|
106821
|
-
const sessionPath =
|
|
106932
|
+
const sessionPath = join31(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
106822
106933
|
if (mode === "json") {
|
|
106823
106934
|
const { setupSession: setupSession2, runModels: runModels2 } = await Promise.resolve().then(() => (init_team_orchestrator(), exports_team_orchestrator));
|
|
106824
106935
|
setupSession2(sessionPath, cliConfig.team, prompt);
|
|
@@ -106828,9 +106939,9 @@ async function runCli() {
|
|
|
106828
106939
|
});
|
|
106829
106940
|
const result = { ...status2, responses: {} };
|
|
106830
106941
|
for (const anonId of Object.keys(status2.models)) {
|
|
106831
|
-
const responsePath =
|
|
106942
|
+
const responsePath = join31(sessionPath, `response-${anonId}.md`);
|
|
106832
106943
|
try {
|
|
106833
|
-
const raw2 =
|
|
106944
|
+
const raw2 = readFileSync25(responsePath, "utf-8").trim();
|
|
106834
106945
|
try {
|
|
106835
106946
|
result.responses[anonId] = JSON.parse(raw2);
|
|
106836
106947
|
} catch {
|