claudish 7.19.2 → 7.20.0
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 +190 -114
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
651
651
|
});
|
|
652
652
|
|
|
653
653
|
// src/version.ts
|
|
654
|
-
var VERSION = "7.
|
|
654
|
+
var VERSION = "7.20.0";
|
|
655
655
|
|
|
656
656
|
// src/logger.ts
|
|
657
657
|
var exports_logger = {};
|
|
@@ -27650,9 +27650,6 @@ function loadConfig() {
|
|
|
27650
27650
|
if (config2.onepasswordEnvironments !== undefined) {
|
|
27651
27651
|
merged.onepasswordEnvironments = config2.onepasswordEnvironments;
|
|
27652
27652
|
}
|
|
27653
|
-
if (config2.anthropicApiBilling !== undefined) {
|
|
27654
|
-
merged.anthropicApiBilling = config2.anthropicApiBilling;
|
|
27655
|
-
}
|
|
27656
27653
|
if (config2.localProviders !== undefined) {
|
|
27657
27654
|
merged.localProviders = Array.from(new Set(config2.localProviders)).sort();
|
|
27658
27655
|
}
|
|
@@ -28326,8 +28323,8 @@ var init_provider_definitions = __esm(() => {
|
|
|
28326
28323
|
shortcuts: ["kc"],
|
|
28327
28324
|
shortestPrefix: "kc",
|
|
28328
28325
|
legacyPrefixes: [{ prefix: "kc/", stripPrefix: true }],
|
|
28329
|
-
nativeModelPatterns: [{ pattern: /^kimi-for-coding
|
|
28330
|
-
|
|
28326
|
+
nativeModelPatterns: [{ pattern: /^kimi-for-coding/i }, { pattern: /^k3(-|$)/i }],
|
|
28327
|
+
modelDiscovery: { path: "/models", format: "openai-models-list" },
|
|
28331
28328
|
isDirectApi: true,
|
|
28332
28329
|
description: "Kimi Coding Plan (kc@)"
|
|
28333
28330
|
},
|
|
@@ -30475,6 +30472,22 @@ function lookupModelForProvider(modelId, provider, cachePath) {
|
|
|
30475
30472
|
return;
|
|
30476
30473
|
return entry.aggregators?.find((a) => a.provider === provider)?.contextWindow ?? entry.contextWindow;
|
|
30477
30474
|
}
|
|
30475
|
+
function resolveSubscriptionRouting(modelId, provider, cachePath) {
|
|
30476
|
+
const entry = findCacheEntry(modelId, cachePath);
|
|
30477
|
+
if (!entry)
|
|
30478
|
+
return { kind: "unknown" };
|
|
30479
|
+
if (entry.subscriptionPlans?.includes(provider)) {
|
|
30480
|
+
const agg = entry.aggregators?.find((a) => a.provider === provider);
|
|
30481
|
+
return agg?.externalId ? { kind: "serves", externalId: agg.externalId } : { kind: "unknown" };
|
|
30482
|
+
}
|
|
30483
|
+
return isSubscriptionPlan(provider, cachePath) ? { kind: "not-served" } : { kind: "unknown" };
|
|
30484
|
+
}
|
|
30485
|
+
function isSubscriptionPlan(provider, cachePath) {
|
|
30486
|
+
const cache = readAllModelsCache(cachePath);
|
|
30487
|
+
if (!cache)
|
|
30488
|
+
return false;
|
|
30489
|
+
return cache.entries.some((e) => e.subscriptionPlans?.includes(provider));
|
|
30490
|
+
}
|
|
30478
30491
|
function findCacheEntry(modelId, cachePath) {
|
|
30479
30492
|
if (modelId.includes("@")) {
|
|
30480
30493
|
throw new Error(`model-catalog lookup received provider-routed ID "${modelId}" \u2014 callers must strip the "@" prefix before calling`);
|
|
@@ -31745,14 +31758,6 @@ var init_web_search_detector = __esm(() => {
|
|
|
31745
31758
|
WEB_SEARCH_NAMES = new Set(["web_search", "brave_web_search", "tavily_search"]);
|
|
31746
31759
|
});
|
|
31747
31760
|
|
|
31748
|
-
// src/handlers/shared/stream-parsers/message-start-usage.ts
|
|
31749
|
-
function messageStartUsage(priorInputTokens) {
|
|
31750
|
-
return {
|
|
31751
|
-
input_tokens: priorInputTokens && priorInputTokens > 0 ? priorInputTokens : 100,
|
|
31752
|
-
output_tokens: 1
|
|
31753
|
-
};
|
|
31754
|
-
}
|
|
31755
|
-
|
|
31756
31761
|
// src/handlers/shared/stream-parsers/openai-sse.ts
|
|
31757
31762
|
function validateToolArguments(toolName, argsStr, toolSchemas, textContent) {
|
|
31758
31763
|
const result = validateAndRepairToolCall(toolName, argsStr, toolSchemas, textContent);
|
|
@@ -31782,7 +31787,7 @@ function createStreamingState() {
|
|
|
31782
31787
|
accumulatedText: ""
|
|
31783
31788
|
};
|
|
31784
31789
|
}
|
|
31785
|
-
function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap
|
|
31790
|
+
function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap) {
|
|
31786
31791
|
log(`[Streaming] ===== HANDLER STARTED for ${target} =====`);
|
|
31787
31792
|
let isClosed = false;
|
|
31788
31793
|
let ping = null;
|
|
@@ -31811,7 +31816,7 @@ data: ${JSON.stringify(d)}
|
|
|
31811
31816
|
model: target,
|
|
31812
31817
|
stop_reason: null,
|
|
31813
31818
|
stop_sequence: null,
|
|
31814
|
-
usage:
|
|
31819
|
+
usage: { input_tokens: 100, output_tokens: 1 }
|
|
31815
31820
|
}
|
|
31816
31821
|
});
|
|
31817
31822
|
send("ping", { type: "ping" });
|
|
@@ -31924,10 +31929,7 @@ data: ${JSON.stringify(d)}
|
|
|
31924
31929
|
send("message_delta", {
|
|
31925
31930
|
type: "message_delta",
|
|
31926
31931
|
delta: { stop_reason: stopReason, stop_sequence: null },
|
|
31927
|
-
usage: {
|
|
31928
|
-
...state.usage?.prompt_tokens ? { input_tokens: state.usage.prompt_tokens } : {},
|
|
31929
|
-
output_tokens: state.usage?.completion_tokens || 0
|
|
31930
|
-
}
|
|
31932
|
+
usage: { output_tokens: state.usage?.completion_tokens || 0 }
|
|
31931
31933
|
});
|
|
31932
31934
|
send("message_stop", { type: "message_stop" });
|
|
31933
31935
|
}
|
|
@@ -31938,7 +31940,7 @@ data: ${JSON.stringify(d)}
|
|
|
31938
31940
|
} else {
|
|
31939
31941
|
const estimatedOutputTokens = Math.ceil(state.accumulatedText.length / 4);
|
|
31940
31942
|
log(`[Streaming] No usage data from provider, estimating: ~${estimatedOutputTokens} output tokens`);
|
|
31941
|
-
onTokenUpdate(
|
|
31943
|
+
onTokenUpdate(100, estimatedOutputTokens);
|
|
31942
31944
|
}
|
|
31943
31945
|
}
|
|
31944
31946
|
if (!isClosed) {
|
|
@@ -37556,7 +37558,7 @@ data: ${JSON.stringify(data)}
|
|
|
37556
37558
|
model: opts.modelName,
|
|
37557
37559
|
stop_reason: null,
|
|
37558
37560
|
stop_sequence: null,
|
|
37559
|
-
usage:
|
|
37561
|
+
usage: { input_tokens: 100, output_tokens: 1 }
|
|
37560
37562
|
}
|
|
37561
37563
|
});
|
|
37562
37564
|
send("ping", { type: "ping" });
|
|
@@ -37600,10 +37602,7 @@ data: ${JSON.stringify(data)}
|
|
|
37600
37602
|
send("message_delta", {
|
|
37601
37603
|
type: "message_delta",
|
|
37602
37604
|
delta: { stop_reason: hasToolCalls ? "tool_use" : "end_turn", stop_sequence: null },
|
|
37603
|
-
usage: {
|
|
37604
|
-
...inputTokens > 0 ? { input_tokens: inputTokens } : {},
|
|
37605
|
-
output_tokens: outputTokens
|
|
37606
|
-
}
|
|
37605
|
+
usage: { output_tokens: outputTokens }
|
|
37607
37606
|
});
|
|
37608
37607
|
send("message_stop", { type: "message_stop" });
|
|
37609
37608
|
}
|
|
@@ -37806,7 +37805,7 @@ data: ${JSON.stringify(data)}
|
|
|
37806
37805
|
model: opts.modelName,
|
|
37807
37806
|
stop_reason: null,
|
|
37808
37807
|
stop_sequence: null,
|
|
37809
|
-
usage:
|
|
37808
|
+
usage: { input_tokens: 100, output_tokens: 1 }
|
|
37810
37809
|
}
|
|
37811
37810
|
});
|
|
37812
37811
|
send("ping", { type: "ping" });
|
|
@@ -37827,10 +37826,7 @@ data: ${JSON.stringify(data)}
|
|
|
37827
37826
|
send("message_delta", {
|
|
37828
37827
|
type: "message_delta",
|
|
37829
37828
|
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
37830
|
-
usage: {
|
|
37831
|
-
...promptTokens > 0 ? { input_tokens: promptTokens } : {},
|
|
37832
|
-
output_tokens: completionTokens
|
|
37833
|
-
}
|
|
37829
|
+
usage: { output_tokens: completionTokens }
|
|
37834
37830
|
});
|
|
37835
37831
|
send("message_stop", { type: "message_stop" });
|
|
37836
37832
|
}
|
|
@@ -37982,7 +37978,7 @@ data: ${JSON.stringify(data)}
|
|
|
37982
37978
|
model: opts.modelName,
|
|
37983
37979
|
stop_reason: null,
|
|
37984
37980
|
stop_sequence: null,
|
|
37985
|
-
usage:
|
|
37981
|
+
usage: { input_tokens: 100, output_tokens: 1 }
|
|
37986
37982
|
}
|
|
37987
37983
|
});
|
|
37988
37984
|
send("ping", { type: "ping" });
|
|
@@ -38245,13 +38241,6 @@ data: ${JSON.stringify(data)}
|
|
|
38245
38241
|
} catch {}
|
|
38246
38242
|
}
|
|
38247
38243
|
}
|
|
38248
|
-
},
|
|
38249
|
-
cancel() {
|
|
38250
|
-
isClosed = true;
|
|
38251
|
-
if (pingInterval) {
|
|
38252
|
-
clearInterval(pingInterval);
|
|
38253
|
-
pingInterval = null;
|
|
38254
|
-
}
|
|
38255
38244
|
}
|
|
38256
38245
|
});
|
|
38257
38246
|
return new Response(stream, {
|
|
@@ -38279,7 +38268,6 @@ class TokenTracker {
|
|
|
38279
38268
|
sessionTotalCost = 0;
|
|
38280
38269
|
sessionInputTokens = 0;
|
|
38281
38270
|
sessionOutputTokens = 0;
|
|
38282
|
-
lastInputTokens = 0;
|
|
38283
38271
|
modelNameOverride;
|
|
38284
38272
|
quotaRemaining;
|
|
38285
38273
|
constructor(port, config2) {
|
|
@@ -38296,11 +38284,10 @@ class TokenTracker {
|
|
|
38296
38284
|
this.quotaRemaining = fraction;
|
|
38297
38285
|
}
|
|
38298
38286
|
rewrite() {
|
|
38299
|
-
this.writeFile(this.
|
|
38287
|
+
this.writeFile(this.sessionInputTokens, this.sessionOutputTokens);
|
|
38300
38288
|
}
|
|
38301
38289
|
update(inputTokens, outputTokens) {
|
|
38302
38290
|
this.sessionInputTokens = inputTokens;
|
|
38303
|
-
this.lastInputTokens = inputTokens;
|
|
38304
38291
|
this.sessionOutputTokens += outputTokens;
|
|
38305
38292
|
const pricing = this.getPricing();
|
|
38306
38293
|
const cost = inputTokens / 1e6 * pricing.inputCostPer1M + outputTokens / 1e6 * pricing.outputCostPer1M;
|
|
@@ -38309,7 +38296,6 @@ class TokenTracker {
|
|
|
38309
38296
|
}
|
|
38310
38297
|
accumulateBoth(inputTokens, outputTokens) {
|
|
38311
38298
|
this.sessionInputTokens += inputTokens;
|
|
38312
|
-
this.lastInputTokens = this.sessionInputTokens;
|
|
38313
38299
|
this.sessionOutputTokens += outputTokens;
|
|
38314
38300
|
const pricing = this.getPricing();
|
|
38315
38301
|
const cost = this.sessionInputTokens / 1e6 * pricing.inputCostPer1M + this.sessionOutputTokens / 1e6 * pricing.outputCostPer1M;
|
|
@@ -38318,7 +38304,6 @@ class TokenTracker {
|
|
|
38318
38304
|
}
|
|
38319
38305
|
updateWithDelta(inputTokens, outputTokens) {
|
|
38320
38306
|
let incrementalInputTokens;
|
|
38321
|
-
this.lastInputTokens = inputTokens;
|
|
38322
38307
|
if (inputTokens >= this.sessionInputTokens) {
|
|
38323
38308
|
incrementalInputTokens = inputTokens - this.sessionInputTokens;
|
|
38324
38309
|
this.sessionInputTokens = inputTokens;
|
|
@@ -38334,11 +38319,10 @@ class TokenTracker {
|
|
|
38334
38319
|
const pricing = this.getPricing();
|
|
38335
38320
|
const cost = incrementalInputTokens / 1e6 * pricing.inputCostPer1M + outputTokens / 1e6 * pricing.outputCostPer1M;
|
|
38336
38321
|
this.sessionTotalCost += cost;
|
|
38337
|
-
this.writeFile(inputTokens, this.sessionOutputTokens, pricing.isEstimate);
|
|
38322
|
+
this.writeFile(Math.max(inputTokens, this.sessionInputTokens), this.sessionOutputTokens, pricing.isEstimate);
|
|
38338
38323
|
}
|
|
38339
38324
|
updateWithActualCost(inputTokens, outputTokens, actualCost) {
|
|
38340
38325
|
this.sessionInputTokens = inputTokens;
|
|
38341
|
-
this.lastInputTokens = inputTokens;
|
|
38342
38326
|
this.sessionOutputTokens += outputTokens;
|
|
38343
38327
|
if (typeof actualCost === "number" && actualCost > 0) {
|
|
38344
38328
|
this.sessionTotalCost += actualCost;
|
|
@@ -38354,7 +38338,6 @@ class TokenTracker {
|
|
|
38354
38338
|
updateLocal(inputTokens, outputTokens) {
|
|
38355
38339
|
if (inputTokens > 0) {
|
|
38356
38340
|
this.sessionInputTokens = inputTokens;
|
|
38357
|
-
this.lastInputTokens = inputTokens;
|
|
38358
38341
|
}
|
|
38359
38342
|
this.sessionOutputTokens += outputTokens;
|
|
38360
38343
|
this.writeFile(this.sessionInputTokens, this.sessionOutputTokens);
|
|
@@ -38368,9 +38351,6 @@ class TokenTracker {
|
|
|
38368
38351
|
getInputTokens() {
|
|
38369
38352
|
return this.sessionInputTokens;
|
|
38370
38353
|
}
|
|
38371
|
-
getLastInputTokens() {
|
|
38372
|
-
return this.lastInputTokens || this.sessionInputTokens;
|
|
38373
|
-
}
|
|
38374
38354
|
getOutputTokens() {
|
|
38375
38355
|
return this.sessionOutputTokens;
|
|
38376
38356
|
}
|
|
@@ -38912,18 +38892,16 @@ class ComposedHandler {
|
|
|
38912
38892
|
}
|
|
38913
38893
|
};
|
|
38914
38894
|
const streamFormat = this.provider.overrideStreamFormat?.() ?? this.explicitAdapter?.getStreamFormat() ?? this.modelAdapter?.getStreamFormat() ?? this.getAdapter().getStreamFormat();
|
|
38915
|
-
const priorInputTokens = this.tokenTracker.getLastInputTokens();
|
|
38916
38895
|
switch (streamFormat) {
|
|
38917
38896
|
case "openai-sse":
|
|
38918
|
-
return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap
|
|
38897
|
+
return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap);
|
|
38919
38898
|
case "openai-responses-sse":
|
|
38920
38899
|
return createResponsesStreamHandler(c, response, {
|
|
38921
38900
|
modelName: this.bareModelName,
|
|
38922
38901
|
onTokenUpdate,
|
|
38923
38902
|
toolNameMap: adapter.getToolNameMap(),
|
|
38924
38903
|
contextWindow: lookupModelForProvider(this.bareModelName, this.provider.name),
|
|
38925
|
-
onApiError
|
|
38926
|
-
priorInputTokens
|
|
38904
|
+
onApiError
|
|
38927
38905
|
});
|
|
38928
38906
|
case "anthropic-sse":
|
|
38929
38907
|
return createAnthropicPassthroughStream(c, response, {
|
|
@@ -38943,15 +38921,13 @@ class ComposedHandler {
|
|
|
38943
38921
|
middlewareManager: this.middlewareManager,
|
|
38944
38922
|
onTokenUpdate,
|
|
38945
38923
|
onToolCall,
|
|
38946
|
-
unwrapResponse: this.options.unwrapGeminiResponse
|
|
38947
|
-
priorInputTokens
|
|
38924
|
+
unwrapResponse: this.options.unwrapGeminiResponse
|
|
38948
38925
|
});
|
|
38949
38926
|
}
|
|
38950
38927
|
case "ollama-jsonl":
|
|
38951
38928
|
return createOllamaJsonlStream(c, response, {
|
|
38952
38929
|
modelName: this.bareModelName,
|
|
38953
|
-
onTokenUpdate
|
|
38954
|
-
priorInputTokens
|
|
38930
|
+
onTokenUpdate
|
|
38955
38931
|
});
|
|
38956
38932
|
default:
|
|
38957
38933
|
throw new Error(`Unknown stream format: ${streamFormat}`);
|
|
@@ -42591,7 +42567,8 @@ var init_default_routing_rules = __esm(() => {
|
|
|
42591
42567
|
"o3-*": ["openai-codex", "openai", "openrouter"],
|
|
42592
42568
|
"gemini-*": ["gemini-codeassist", "google", "openrouter"],
|
|
42593
42569
|
"grok-*": ["x-ai", "openrouter"],
|
|
42594
|
-
"kimi-*": ["kimi-coding
|
|
42570
|
+
"kimi-*": ["kimi-coding", "kimi", "openrouter"],
|
|
42571
|
+
"k3*": ["kimi-coding", "kimi", "openrouter"],
|
|
42595
42572
|
"minimax-*": ["minimax-coding", "minimax", "openrouter"],
|
|
42596
42573
|
"glm-*": ["glm-coding", "glm", "openrouter"],
|
|
42597
42574
|
"z-ai-*": ["z-ai", "openrouter"],
|
|
@@ -42645,7 +42622,7 @@ function matchRoutingRule(modelName, rules) {
|
|
|
42645
42622
|
return rules["*"];
|
|
42646
42623
|
return null;
|
|
42647
42624
|
}
|
|
42648
|
-
function buildRoutingChain(entries, originalModelName) {
|
|
42625
|
+
function buildRoutingChain(entries, originalModelName, cachePath) {
|
|
42649
42626
|
const routes = [];
|
|
42650
42627
|
for (const entry of entries) {
|
|
42651
42628
|
const atIdx = entry.indexOf("@");
|
|
@@ -42659,6 +42636,13 @@ function buildRoutingChain(entries, originalModelName) {
|
|
|
42659
42636
|
modelName = originalModelName;
|
|
42660
42637
|
}
|
|
42661
42638
|
const provider = PROVIDER_SHORTCUTS[providerRaw.toLowerCase()] ?? providerRaw.toLowerCase();
|
|
42639
|
+
if (atIdx === -1) {
|
|
42640
|
+
const routing = resolveSubscriptionRouting(modelName, provider, cachePath);
|
|
42641
|
+
if (routing.kind === "not-served")
|
|
42642
|
+
continue;
|
|
42643
|
+
if (routing.kind === "serves")
|
|
42644
|
+
modelName = routing.externalId;
|
|
42645
|
+
}
|
|
42662
42646
|
let modelSpec;
|
|
42663
42647
|
if (provider === "openrouter") {
|
|
42664
42648
|
const resolution = resolveModelNameSync(modelName, "openrouter");
|
|
@@ -42685,7 +42669,7 @@ function globMatch(pattern, value) {
|
|
|
42685
42669
|
async function hasCredentialsForProvider(provider) {
|
|
42686
42670
|
return credentials.isAvailable(provider);
|
|
42687
42671
|
}
|
|
42688
|
-
async function routeExplicit(modelSpec, model, provider) {
|
|
42672
|
+
async function routeExplicit(modelSpec, model, provider, cachePath) {
|
|
42689
42673
|
if (!await hasCredentialsForProvider(provider)) {
|
|
42690
42674
|
return {
|
|
42691
42675
|
kind: "no-route",
|
|
@@ -42693,7 +42677,7 @@ async function routeExplicit(modelSpec, model, provider) {
|
|
|
42693
42677
|
hint: buildCredentialHint(model, [provider]) ?? undefined
|
|
42694
42678
|
};
|
|
42695
42679
|
}
|
|
42696
|
-
const built = buildRoutingChain([modelSpec], model)[0];
|
|
42680
|
+
const built = buildRoutingChain([modelSpec], model, cachePath)[0];
|
|
42697
42681
|
if (!built) {
|
|
42698
42682
|
return {
|
|
42699
42683
|
kind: "no-route",
|
|
@@ -42702,7 +42686,7 @@ async function routeExplicit(modelSpec, model, provider) {
|
|
|
42702
42686
|
}
|
|
42703
42687
|
return { kind: "ok", primary: built, fallbacks: [] };
|
|
42704
42688
|
}
|
|
42705
|
-
async function routeBare(model, nativeProvider, rules, defaultProvider) {
|
|
42689
|
+
async function routeBare(model, nativeProvider, rules, defaultProvider, cachePath) {
|
|
42706
42690
|
const matched = matchRoutingRule(model, rules) ?? [];
|
|
42707
42691
|
const entries = [...matched];
|
|
42708
42692
|
if (defaultProvider && defaultProvider.length > 0) {
|
|
@@ -42723,7 +42707,7 @@ async function routeBare(model, nativeProvider, rules, defaultProvider) {
|
|
|
42723
42707
|
hint: buildCredentialHint(model, [nativeProvider]) ?? undefined
|
|
42724
42708
|
};
|
|
42725
42709
|
}
|
|
42726
|
-
const candidates = buildRoutingChain(entries, model);
|
|
42710
|
+
const candidates = buildRoutingChain(entries, model, cachePath);
|
|
42727
42711
|
const credentialed = [];
|
|
42728
42712
|
const skipped = [];
|
|
42729
42713
|
const checks4 = await Promise.all(candidates.map((candidate) => hasCredentialsForProvider(candidate.provider)));
|
|
@@ -42744,16 +42728,17 @@ async function routeBare(model, nativeProvider, rules, defaultProvider) {
|
|
|
42744
42728
|
const [primary, ...fallbacks] = credentialed;
|
|
42745
42729
|
return { kind: "ok", primary, fallbacks };
|
|
42746
42730
|
}
|
|
42747
|
-
async function route(modelSpec, rulesOverride, defaultProviderOverride) {
|
|
42731
|
+
async function route(modelSpec, rulesOverride, defaultProviderOverride, cachePath) {
|
|
42748
42732
|
const parsed = parseModelSpec(modelSpec);
|
|
42749
42733
|
if (parsed.isExplicitProvider) {
|
|
42750
|
-
return routeExplicit(modelSpec, parsed.model, parsed.provider);
|
|
42734
|
+
return routeExplicit(modelSpec, parsed.model, parsed.provider, cachePath);
|
|
42751
42735
|
}
|
|
42752
42736
|
const rules = rulesOverride ?? loadRoutingRules();
|
|
42753
42737
|
const defaultProvider = defaultProviderOverride !== undefined ? defaultProviderOverride : rulesOverride !== undefined ? undefined : loadConfig().defaultProvider;
|
|
42754
|
-
return routeBare(parsed.model, parsed.provider, rules, defaultProvider);
|
|
42738
|
+
return routeBare(parsed.model, parsed.provider, rules, defaultProvider, cachePath);
|
|
42755
42739
|
}
|
|
42756
42740
|
var init_routing_rules = __esm(() => {
|
|
42741
|
+
init_model_catalog();
|
|
42757
42742
|
init_authority();
|
|
42758
42743
|
init_profile_config();
|
|
42759
42744
|
init_auto_route();
|
|
@@ -58426,8 +58411,7 @@ var init_config = __esm(() => {
|
|
|
58426
58411
|
OPENAI_BASE_URL: "OPENAI_BASE_URL",
|
|
58427
58412
|
CLAUDISH_SUMMARIZE_TOOLS: "CLAUDISH_SUMMARIZE_TOOLS",
|
|
58428
58413
|
CLAUDISH_DIAG_MODE: "CLAUDISH_DIAG_MODE",
|
|
58429
|
-
CLAUDISH_DEBUG: "CLAUDISH_DEBUG"
|
|
58430
|
-
CLAUDISH_ANTHROPIC_API_BILLING: "CLAUDISH_ANTHROPIC_API_BILLING"
|
|
58414
|
+
CLAUDISH_DEBUG: "CLAUDISH_DEBUG"
|
|
58431
58415
|
};
|
|
58432
58416
|
OPENROUTER_HEADERS = {
|
|
58433
58417
|
"HTTP-Referer": "https://claudish.com",
|
|
@@ -58584,6 +58568,114 @@ var init_model_catalog2 = __esm(() => {
|
|
|
58584
58568
|
NO_CATALOG_VENDOR_SLUGS = new Set(["litellm", "ollama", "lmstudio", "lm-studio"]);
|
|
58585
58569
|
});
|
|
58586
58570
|
|
|
58571
|
+
// src/providers/model-discovery.ts
|
|
58572
|
+
function resolveBaseUrl2(catalogName) {
|
|
58573
|
+
const def = getProviderByName(catalogName);
|
|
58574
|
+
if (!def)
|
|
58575
|
+
return null;
|
|
58576
|
+
for (const envVar of def.baseUrlEnvVars ?? []) {
|
|
58577
|
+
const v = process.env[envVar];
|
|
58578
|
+
if (v)
|
|
58579
|
+
return v.replace(/\/+$/, "");
|
|
58580
|
+
}
|
|
58581
|
+
return (def.baseUrl || "").replace(/\/+$/, "") || null;
|
|
58582
|
+
}
|
|
58583
|
+
function readContextWindow(row) {
|
|
58584
|
+
for (const field of ["context_length", "context_window", "max_context_length"]) {
|
|
58585
|
+
const v = row[field];
|
|
58586
|
+
if (typeof v === "number" && Number.isFinite(v) && v > 0)
|
|
58587
|
+
return v;
|
|
58588
|
+
}
|
|
58589
|
+
return;
|
|
58590
|
+
}
|
|
58591
|
+
function parseOpenAIModelsList(body) {
|
|
58592
|
+
const data = body?.data;
|
|
58593
|
+
if (!Array.isArray(data))
|
|
58594
|
+
return [];
|
|
58595
|
+
const models = [];
|
|
58596
|
+
for (const raw2 of data) {
|
|
58597
|
+
if (!raw2 || typeof raw2 !== "object")
|
|
58598
|
+
continue;
|
|
58599
|
+
const row = raw2;
|
|
58600
|
+
const id = row.id;
|
|
58601
|
+
if (typeof id !== "string" || id.trim().length === 0)
|
|
58602
|
+
continue;
|
|
58603
|
+
const displayName = typeof row.display_name === "string" ? row.display_name : undefined;
|
|
58604
|
+
models.push({ id, displayName, contextWindow: readContextWindow(row) });
|
|
58605
|
+
}
|
|
58606
|
+
return models;
|
|
58607
|
+
}
|
|
58608
|
+
async function discoverProviderModels(providerName) {
|
|
58609
|
+
const cached2 = _cache2.get(providerName);
|
|
58610
|
+
if (cached2 && cached2.expiresAt > Date.now())
|
|
58611
|
+
return cached2.models;
|
|
58612
|
+
const def = getProviderByName(providerName);
|
|
58613
|
+
const descriptor = def?.modelDiscovery;
|
|
58614
|
+
if (!def || !descriptor)
|
|
58615
|
+
return [];
|
|
58616
|
+
const baseUrl = resolveBaseUrl2(providerName);
|
|
58617
|
+
if (!baseUrl)
|
|
58618
|
+
return [];
|
|
58619
|
+
const endpoint = `${baseUrl}${descriptor.path}`;
|
|
58620
|
+
let headers = {};
|
|
58621
|
+
try {
|
|
58622
|
+
const auth = await credentials.getRequestAuth(providerName, { model: "" });
|
|
58623
|
+
headers = { ...auth.headers };
|
|
58624
|
+
} catch (e) {
|
|
58625
|
+
log(`[model-discovery:${providerName}] no credentials, skipping: ${e?.message}`);
|
|
58626
|
+
return [];
|
|
58627
|
+
}
|
|
58628
|
+
let response;
|
|
58629
|
+
try {
|
|
58630
|
+
response = await fetch(endpoint, {
|
|
58631
|
+
method: "GET",
|
|
58632
|
+
headers,
|
|
58633
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
58634
|
+
});
|
|
58635
|
+
} catch (e) {
|
|
58636
|
+
log(`[model-discovery:${providerName}] fetch failed: ${e?.message}`);
|
|
58637
|
+
return [];
|
|
58638
|
+
}
|
|
58639
|
+
if (!response.ok) {
|
|
58640
|
+
log(`[model-discovery:${providerName}] HTTP ${response.status} from ${endpoint}`);
|
|
58641
|
+
return [];
|
|
58642
|
+
}
|
|
58643
|
+
let body;
|
|
58644
|
+
try {
|
|
58645
|
+
body = await response.json();
|
|
58646
|
+
} catch {
|
|
58647
|
+
log(`[model-discovery:${providerName}] response was not JSON`);
|
|
58648
|
+
return [];
|
|
58649
|
+
}
|
|
58650
|
+
const models = parseOpenAIModelsList(body);
|
|
58651
|
+
if (models.length === 0) {
|
|
58652
|
+
log(`[model-discovery:${providerName}] endpoint reachable but listed no models`);
|
|
58653
|
+
return [];
|
|
58654
|
+
}
|
|
58655
|
+
log(`[model-discovery:${providerName}] discovered ${models.length} models: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
|
|
58656
|
+
_cache2.set(providerName, { models, expiresAt: Date.now() + CACHE_TTL_MS3 });
|
|
58657
|
+
return models;
|
|
58658
|
+
}
|
|
58659
|
+
async function discoverContextWindow(providerName, modelId) {
|
|
58660
|
+
const models = await discoverProviderModels(providerName);
|
|
58661
|
+
const match2 = models.find((m) => m.id.toLowerCase() === modelId.toLowerCase());
|
|
58662
|
+
return match2?.contextWindow;
|
|
58663
|
+
}
|
|
58664
|
+
function rankDiscoveredModels(models) {
|
|
58665
|
+
return [...models].sort((a, b) => {
|
|
58666
|
+
const diff = (b.contextWindow ?? 0) - (a.contextWindow ?? 0);
|
|
58667
|
+
return diff !== 0 ? diff : a.id.localeCompare(b.id);
|
|
58668
|
+
});
|
|
58669
|
+
}
|
|
58670
|
+
var CACHE_TTL_MS3, FETCH_TIMEOUT_MS2 = 5000, _cache2;
|
|
58671
|
+
var init_model_discovery = __esm(() => {
|
|
58672
|
+
init_authority();
|
|
58673
|
+
init_logger();
|
|
58674
|
+
init_provider_definitions();
|
|
58675
|
+
CACHE_TTL_MS3 = 5 * 60 * 1000;
|
|
58676
|
+
_cache2 = new Map;
|
|
58677
|
+
});
|
|
58678
|
+
|
|
58587
58679
|
// src/providers/ollama-discovery.ts
|
|
58588
58680
|
function ollamaBaseUrl() {
|
|
58589
58681
|
return process.env.OLLAMA_HOST || process.env.OLLAMA_BASE_URL || "http://localhost:11434";
|
|
@@ -59153,8 +59245,22 @@ async function selectModelFromProvider(provider, tierName, recommendedModels, _f
|
|
|
59153
59245
|
const prefix = PROVIDER_MODEL_PREFIX[provider] || `${provider}@`;
|
|
59154
59246
|
const displayName = getPickerDisplayName(provider);
|
|
59155
59247
|
const def = getProviderByName(provider);
|
|
59156
|
-
if (def?.
|
|
59157
|
-
|
|
59248
|
+
if (def?.modelDiscovery) {
|
|
59249
|
+
const discovered = rankDiscoveredModels(await discoverProviderModels(provider));
|
|
59250
|
+
if (discovered.length > 0) {
|
|
59251
|
+
const discoveredModels = discovered.map((m) => ({
|
|
59252
|
+
id: m.id,
|
|
59253
|
+
name: m.displayName || m.id,
|
|
59254
|
+
description: m.contextWindow ? `${m.displayName ?? m.id} \xB7 ${Math.round(m.contextWindow / 1024)}K context` : m.displayName ?? m.id,
|
|
59255
|
+
provider: displayName,
|
|
59256
|
+
supportsTools: true,
|
|
59257
|
+
isFree: true,
|
|
59258
|
+
source: displayName
|
|
59259
|
+
}));
|
|
59260
|
+
const picked = await pickModelFromList(provider, displayName, tierName, discoveredModels);
|
|
59261
|
+
if (picked)
|
|
59262
|
+
return picked;
|
|
59263
|
+
}
|
|
59158
59264
|
}
|
|
59159
59265
|
if (provider === "ollama") {
|
|
59160
59266
|
const ollamaModels = await fetchOllamaModels2({ enrichCapabilities: false });
|
|
@@ -59333,6 +59439,7 @@ var init_model_selector = __esm(() => {
|
|
|
59333
59439
|
init_authority();
|
|
59334
59440
|
init_model_loader();
|
|
59335
59441
|
init_model_catalog2();
|
|
59442
|
+
init_model_discovery();
|
|
59336
59443
|
init_provider_definitions();
|
|
59337
59444
|
pickerProviderToFirebaseSlug = {
|
|
59338
59445
|
openrouter: "openrouter",
|
|
@@ -62384,8 +62491,6 @@ async function parseArgs(args) {
|
|
|
62384
62491
|
process.exit(1);
|
|
62385
62492
|
}
|
|
62386
62493
|
config3.defaultProvider = dpArg;
|
|
62387
|
-
} else if (arg === "--anthropic-api-billing") {
|
|
62388
|
-
config3.anthropicApiBilling = true;
|
|
62389
62494
|
} else if (arg === "--op-env" || arg.startsWith("--op-env=")) {
|
|
62390
62495
|
const v = arg.startsWith("--op-env=") ? arg.slice("--op-env=".length) : args[++i];
|
|
62391
62496
|
if (!v) {
|
|
@@ -63435,10 +63540,6 @@ ${h("OPTIONS")}
|
|
|
63435
63540
|
${green("--profile")} ${yellow("<name>")} Use named profile for model mapping (default profile if omitted)
|
|
63436
63541
|
${green("--default-provider")} ${yellow("<name>")} Fallback provider for bare model names (builtin or customEndpoints key)
|
|
63437
63542
|
${dim("Precedence: this flag > CLAUDISH_DEFAULT_PROVIDER env > config.json")}
|
|
63438
|
-
${green("--anthropic-api-billing")} Use your real ANTHROPIC_API_KEY for native Claude models
|
|
63439
|
-
${dim("(metered API billing). Default: the key is hidden so Claude Code")}
|
|
63440
|
-
${dim("uses your claude.ai subscription. Env: CLAUDISH_ANTHROPIC_API_BILLING")}
|
|
63441
|
-
${dim("Config: anthropicApiBilling: true")}
|
|
63442
63543
|
${green("--config")} ${yellow("<file>")} Use THIS config file for the run, fully replacing the machine
|
|
63443
63544
|
${dim("global (~/.claudish/config.json) AND project (.claudish.json).")}
|
|
63444
63545
|
${dim("A file naming no op:// source never touches 1Password (no prompt).")}
|
|
@@ -63614,7 +63715,6 @@ ${h("ENVIRONMENT VARIABLES")}
|
|
|
63614
63715
|
${blue("CLAUDISH_CONTEXT_WINDOW")} Override context window size
|
|
63615
63716
|
${blue("CLAUDISH_DIAG_MODE")} Diagnostic output: auto / logfile / off
|
|
63616
63717
|
${blue("CLAUDISH_DEBUG")} Always enable debug logging: 1 / true ${dim("(same as -d)")}
|
|
63617
|
-
${blue("CLAUDISH_ANTHROPIC_API_BILLING")} Bill native Claude to your API key ${dim("(see --anthropic-api-billing)")}
|
|
63618
63718
|
${blue("CLAUDISH_MCP_TOOLS")} MCP tool gating: all / low-level / agentic / channel
|
|
63619
63719
|
${blue("CLAUDISH_MODEL_OPUS")} Override model for Opus role
|
|
63620
63720
|
${blue("CLAUDISH_MODEL_SONNET")} Override model for Sonnet role
|
|
@@ -64740,7 +64840,7 @@ function writeProbeModelsCache(data, path2 = PROBE_MODELS_CACHE_PATH) {
|
|
|
64740
64840
|
mkdirSync14(dirname7(path2), { recursive: true });
|
|
64741
64841
|
writeFileSync16(path2, JSON.stringify(data), "utf-8");
|
|
64742
64842
|
}
|
|
64743
|
-
function isCacheFresh(data, ttlMs =
|
|
64843
|
+
function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
|
|
64744
64844
|
if (!data?.generatedAt)
|
|
64745
64845
|
return false;
|
|
64746
64846
|
const generatedMs = Date.parse(data.generatedAt);
|
|
@@ -64748,7 +64848,7 @@ function isCacheFresh(data, ttlMs = CACHE_TTL_MS3) {
|
|
|
64748
64848
|
return false;
|
|
64749
64849
|
return Date.now() - generatedMs < ttlMs;
|
|
64750
64850
|
}
|
|
64751
|
-
async function fetchProbeModels(url2 = PROBE_MODELS_URL, timeoutMs =
|
|
64851
|
+
async function fetchProbeModels(url2 = PROBE_MODELS_URL, timeoutMs = FETCH_TIMEOUT_MS3) {
|
|
64752
64852
|
let response;
|
|
64753
64853
|
try {
|
|
64754
64854
|
response = await fetch(url2, { signal: AbortSignal.timeout(timeoutMs) });
|
|
@@ -64854,9 +64954,9 @@ function isValidResponse(raw2) {
|
|
|
64854
64954
|
return false;
|
|
64855
64955
|
return true;
|
|
64856
64956
|
}
|
|
64857
|
-
var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels",
|
|
64957
|
+
var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels", CACHE_TTL_MS4, FETCH_TIMEOUT_MS3 = 15000, PROBE_MODELS_CACHE_PATH, _inFlight = null;
|
|
64858
64958
|
var init_probe_catalog = __esm(() => {
|
|
64859
|
-
|
|
64959
|
+
CACHE_TTL_MS4 = 60 * 60 * 1000;
|
|
64860
64960
|
PROBE_MODELS_CACHE_PATH = join24(homedir23(), ".claudish", "probe-models.json");
|
|
64861
64961
|
});
|
|
64862
64962
|
|
|
@@ -71184,8 +71284,7 @@ __export(exports_claude_runner, {
|
|
|
71184
71284
|
isProxyAuthMode: () => isProxyAuthMode,
|
|
71185
71285
|
computeMainThreadContextWindow: () => computeMainThreadContextWindow,
|
|
71186
71286
|
checkClaudeInstalled: () => checkClaudeInstalled,
|
|
71187
|
-
buildClaudishSettingsOverlay: () => buildClaudishSettingsOverlay
|
|
71188
|
-
MIN_AUTO_COMPACT_WINDOW: () => MIN_AUTO_COMPACT_WINDOW
|
|
71287
|
+
buildClaudishSettingsOverlay: () => buildClaudishSettingsOverlay
|
|
71189
71288
|
});
|
|
71190
71289
|
import { spawn as spawn4 } from "child_process";
|
|
71191
71290
|
import {
|
|
@@ -71216,18 +71315,6 @@ function hasNativeAnthropicMapping(config3) {
|
|
|
71216
71315
|
];
|
|
71217
71316
|
return models.some((m) => m && parseModelSpec(m).provider === "native-anthropic");
|
|
71218
71317
|
}
|
|
71219
|
-
function wantsAnthropicApiBilling(config3) {
|
|
71220
|
-
if (config3.anthropicApiBilling)
|
|
71221
|
-
return true;
|
|
71222
|
-
const raw2 = process.env[ENV.CLAUDISH_ANTHROPIC_API_BILLING];
|
|
71223
|
-
if (raw2 !== undefined && raw2 !== "" && raw2 !== "0" && raw2.toLowerCase() !== "false")
|
|
71224
|
-
return true;
|
|
71225
|
-
try {
|
|
71226
|
-
return loadConfig().anthropicApiBilling === true;
|
|
71227
|
-
} catch {
|
|
71228
|
-
return false;
|
|
71229
|
-
}
|
|
71230
|
-
}
|
|
71231
71318
|
function isProxyAuthMode(config3) {
|
|
71232
71319
|
return !config3.monitor && !hasNativeAnthropicMapping(config3);
|
|
71233
71320
|
}
|
|
@@ -71435,7 +71522,7 @@ async function computeMainThreadContextWindow(config3, cachePath) {
|
|
|
71435
71522
|
continue;
|
|
71436
71523
|
provider = plan.primary.provider;
|
|
71437
71524
|
}
|
|
71438
|
-
const win = lookupModelForProvider(parsed.model, provider, cachePath);
|
|
71525
|
+
const win = await discoverContextWindow(provider, parsed.model) ?? lookupModelForProvider(parsed.model, provider, cachePath);
|
|
71439
71526
|
if (typeof win === "number" && win > 0) {
|
|
71440
71527
|
min = Math.min(min, win);
|
|
71441
71528
|
}
|
|
@@ -71491,7 +71578,6 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
71491
71578
|
[ENV.CLAUDISH_ACTIVE_MODEL_NAME]: modelDisplayName,
|
|
71492
71579
|
CLAUDISH_IS_LOCAL: isLocalModel2 ? "true" : "false"
|
|
71493
71580
|
};
|
|
71494
|
-
let hidAnthropicApiKey = false;
|
|
71495
71581
|
delete env.CLAUDECODE;
|
|
71496
71582
|
if (config3.monitor) {
|
|
71497
71583
|
delete env.ANTHROPIC_API_KEY;
|
|
@@ -71505,23 +71591,16 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
71505
71591
|
env[ENV.ANTHROPIC_MODEL] = modelId;
|
|
71506
71592
|
env[ENV.ANTHROPIC_SMALL_FAST_MODEL] = modelId;
|
|
71507
71593
|
}
|
|
71508
|
-
if (hasNativeAnthropicMapping(config3)) {
|
|
71509
|
-
|
|
71510
|
-
|
|
71511
|
-
hidAnthropicApiKey = true;
|
|
71512
|
-
}
|
|
71513
|
-
} else {
|
|
71514
|
-
env.ANTHROPIC_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
|
|
71515
|
-
env.ANTHROPIC_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth";
|
|
71594
|
+
if (hasNativeAnthropicMapping(config3)) {} else {
|
|
71595
|
+
env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
|
|
71596
|
+
env.ANTHROPIC_AUTH_TOKEN = process.env.ANTHROPIC_AUTH_TOKEN || "placeholder-token-not-used-proxy-handles-auth";
|
|
71516
71597
|
if (!process.env[ENV.CLAUDE_CODE_AUTO_COMPACT_WINDOW]) {
|
|
71517
71598
|
const autoCompactWindow = await computeMainThreadContextWindow(config3);
|
|
71518
|
-
if (autoCompactWindow
|
|
71599
|
+
if (autoCompactWindow > 0) {
|
|
71519
71600
|
env[ENV.CLAUDE_CODE_AUTO_COMPACT_WINDOW] = String(autoCompactWindow);
|
|
71520
71601
|
if (!config3.quiet) {
|
|
71521
71602
|
console.error(`[claudish] Auto-compact window: ${autoCompactWindow.toLocaleString()} tokens ` + "(Claude Code compacts before the backend's real limit)");
|
|
71522
71603
|
}
|
|
71523
|
-
} else if (autoCompactWindow > 0 && !config3.quiet) {
|
|
71524
|
-
console.error(`[claudish] Model's real context window (${autoCompactWindow.toLocaleString()}) is below ` + `Claude Code's ${MIN_AUTO_COMPACT_WINDOW.toLocaleString()}-token auto-compact floor \u2014 ` + "leaving CLAUDE_CODE_AUTO_COMPACT_WINDOW unset so native auto-compaction stays on.");
|
|
71525
71604
|
}
|
|
71526
71605
|
}
|
|
71527
71606
|
}
|
|
@@ -71537,9 +71616,6 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
71537
71616
|
};
|
|
71538
71617
|
if (!config3.monitor && hasNativeAnthropicMapping(config3)) {
|
|
71539
71618
|
log2("[claudish] Native Claude model detected \u2014 using Claude Code subscription credentials");
|
|
71540
|
-
if (hidAnthropicApiKey) {
|
|
71541
|
-
log2("[claudish] ANTHROPIC_API_KEY found but hidden so it can't override that subscription \xB7 " + "use --anthropic-api-billing (or anthropicApiBilling: true) to bill the API instead");
|
|
71542
|
-
}
|
|
71543
71619
|
}
|
|
71544
71620
|
if (config3.interactive) {
|
|
71545
71621
|
log2(`
|
|
@@ -71706,12 +71782,12 @@ async function checkClaudeInstalled() {
|
|
|
71706
71782
|
const binary = await findClaudeBinary();
|
|
71707
71783
|
return binary !== null;
|
|
71708
71784
|
}
|
|
71709
|
-
var restoreTerminal = null
|
|
71785
|
+
var restoreTerminal = null;
|
|
71710
71786
|
var init_claude_runner = __esm(() => {
|
|
71711
71787
|
init_model_catalog();
|
|
71712
71788
|
init_config();
|
|
71713
71789
|
init_logger();
|
|
71714
|
-
|
|
71790
|
+
init_model_discovery();
|
|
71715
71791
|
init_model_parser();
|
|
71716
71792
|
init_routing_rules();
|
|
71717
71793
|
init_telemetry();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.20.0",
|
|
4
4
|
"description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"ai"
|
|
61
61
|
],
|
|
62
62
|
"optionalDependencies": {
|
|
63
|
-
"@claudish/magmux-darwin-arm64": "7.
|
|
64
|
-
"@claudish/magmux-darwin-x64": "7.
|
|
65
|
-
"@claudish/magmux-linux-arm64": "7.
|
|
66
|
-
"@claudish/magmux-linux-x64": "7.
|
|
63
|
+
"@claudish/magmux-darwin-arm64": "7.20.0",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "7.20.0",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "7.20.0",
|
|
66
|
+
"@claudish/magmux-linux-x64": "7.20.0"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|