crosscheck-mcp 0.2.14 → 0.2.15
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/browser-ext.cjs +154 -74
- package/dist/browser-ext.cjs.map +1 -1
- package/dist/browser-ext.js +154 -74
- package/dist/browser-ext.js.map +1 -1
- package/dist/node-stdio.cjs +150 -78
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.d.cts +9 -0
- package/dist/node-stdio.d.ts +9 -0
- package/dist/node-stdio.js +147 -75
- package/dist/node-stdio.js.map +1 -1
- package/package.json +1 -1
package/dist/node-stdio.d.cts
CHANGED
|
@@ -436,6 +436,15 @@ interface Provider {
|
|
|
436
436
|
readonly name: string;
|
|
437
437
|
/** Default model for this provider (env-resolved at factory time). */
|
|
438
438
|
readonly model: string;
|
|
439
|
+
/** Ordered fallback models — "greenlight" candidates to try, in order,
|
|
440
|
+
* when `model` comes back with a model-access failure (the account/
|
|
441
|
+
* project doesn't have it enabled) rather than any other kind of
|
|
442
|
+
* error. Env-resolved at factory time from `<PROVIDER>_MODEL_
|
|
443
|
+
* FALLBACKS`, or set from a user's/org's configured chain. Empty for
|
|
444
|
+
* most providers — a bad key or rate limit isn't fixed by switching
|
|
445
|
+
* models, so this is only ever consulted for that one failure mode
|
|
446
|
+
* (see core/model-fallback.ts). */
|
|
447
|
+
readonly fallbackModels?: readonly string[];
|
|
439
448
|
/** Make a request and return the parsed result. Throws `ProviderError`
|
|
440
449
|
* on classified failures (auth, rate_limit, timeout, server, parse,
|
|
441
450
|
* network, client). */
|
package/dist/node-stdio.d.ts
CHANGED
|
@@ -436,6 +436,15 @@ interface Provider {
|
|
|
436
436
|
readonly name: string;
|
|
437
437
|
/** Default model for this provider (env-resolved at factory time). */
|
|
438
438
|
readonly model: string;
|
|
439
|
+
/** Ordered fallback models — "greenlight" candidates to try, in order,
|
|
440
|
+
* when `model` comes back with a model-access failure (the account/
|
|
441
|
+
* project doesn't have it enabled) rather than any other kind of
|
|
442
|
+
* error. Env-resolved at factory time from `<PROVIDER>_MODEL_
|
|
443
|
+
* FALLBACKS`, or set from a user's/org's configured chain. Empty for
|
|
444
|
+
* most providers — a bad key or rate limit isn't fixed by switching
|
|
445
|
+
* models, so this is only ever consulted for that one failure mode
|
|
446
|
+
* (see core/model-fallback.ts). */
|
|
447
|
+
readonly fallbackModels?: readonly string[];
|
|
439
448
|
/** Make a request and return the parsed result. Throws `ProviderError`
|
|
440
449
|
* on classified failures (auth, rate_limit, timeout, server, parse,
|
|
441
450
|
* network, client). */
|
package/dist/node-stdio.js
CHANGED
|
@@ -1218,11 +1218,18 @@ var ProviderError = class extends Error {
|
|
|
1218
1218
|
status;
|
|
1219
1219
|
transient;
|
|
1220
1220
|
retryAfterS;
|
|
1221
|
+
/** True specifically for "the key is fine but this model isn't
|
|
1222
|
+
* available to this account/project" (see http-errors.ts's
|
|
1223
|
+
* isModelAccessFailure) — the one failure a model fallback chain can
|
|
1224
|
+
* actually fix. Distinct from `transient`: this is never worth
|
|
1225
|
+
* retrying the SAME model, but IS worth trying a different one. */
|
|
1226
|
+
modelAccessFailure;
|
|
1221
1227
|
constructor(kind, message, opts) {
|
|
1222
1228
|
super(message);
|
|
1223
1229
|
this.kind = kind;
|
|
1224
1230
|
this.status = opts?.status;
|
|
1225
1231
|
this.transient = opts?.transient ?? defaultTransient(kind);
|
|
1232
|
+
this.modelAccessFailure = opts?.modelAccessFailure ?? false;
|
|
1226
1233
|
if (opts?.retryAfterS !== void 0) {
|
|
1227
1234
|
this.retryAfterS = opts.retryAfterS;
|
|
1228
1235
|
}
|
|
@@ -1254,7 +1261,7 @@ function httpFailureToProviderError(provider, status, bodyText, retryAfterS, mod
|
|
|
1254
1261
|
return new ProviderError(
|
|
1255
1262
|
"client",
|
|
1256
1263
|
`${provider}: your account/project doesn't have access to ${modelRef} (HTTP ${status}). This is a model-access problem, not a key problem \u2014 your ${provider} API key is fine, ${modelRef} just isn't enabled for this account/project. Fix: run \`crosscheck models set ${provider} <a-model-you-have-access-to>\` (or set ${provider.toUpperCase()}_MODEL in your .env until that's available). Detail: ${detail}`,
|
|
1257
|
-
{ status }
|
|
1264
|
+
{ status, modelAccessFailure: true }
|
|
1258
1265
|
);
|
|
1259
1266
|
}
|
|
1260
1267
|
if (isCreditsFailure(status, bodyText)) {
|
|
@@ -1470,6 +1477,14 @@ function buildAnthropicRequest(opts) {
|
|
|
1470
1477
|
if (system !== void 0) {
|
|
1471
1478
|
body.system = system;
|
|
1472
1479
|
}
|
|
1480
|
+
if (isReasoningModel("anthropic", opts.model)) {
|
|
1481
|
+
if (opts.model.toLowerCase().startsWith("claude-fable-5")) {
|
|
1482
|
+
body.thinking = { type: "adaptive" };
|
|
1483
|
+
body.output_config = { effort: "low" };
|
|
1484
|
+
} else {
|
|
1485
|
+
body.thinking = { type: "disabled" };
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1473
1488
|
if (opts.jsonSchema) {
|
|
1474
1489
|
body.tools = [{
|
|
1475
1490
|
name: ANTHROPIC_STRUCTURED_TOOL_NAME,
|
|
@@ -1537,7 +1552,12 @@ function parseAnthropicResponse(opts) {
|
|
|
1537
1552
|
purpose: opts.purpose
|
|
1538
1553
|
};
|
|
1539
1554
|
usage.total_tokens = usage.prompt_tokens + usage.completion_tokens;
|
|
1540
|
-
|
|
1555
|
+
const stopReasonRaw = r["stop_reason"];
|
|
1556
|
+
const stopReason = typeof stopReasonRaw === "string" ? stopReasonRaw : void 0;
|
|
1557
|
+
return { text, usage, ...stopReason !== void 0 ? { stopReason } : {} };
|
|
1558
|
+
}
|
|
1559
|
+
function isEmptyDueToMaxTokens(text, stopReason) {
|
|
1560
|
+
return text.trim() === "" && stopReason === "max_tokens";
|
|
1541
1561
|
}
|
|
1542
1562
|
function applyPricing(usage, pricing) {
|
|
1543
1563
|
const { cost_usd, estimated } = calculateCost(
|
|
@@ -1555,49 +1575,64 @@ function applyPricing(usage, pricing) {
|
|
|
1555
1575
|
estimated: usage.estimated || estimated
|
|
1556
1576
|
};
|
|
1557
1577
|
}
|
|
1578
|
+
var MAX_TOKENS_ESCALATIONS = 2;
|
|
1579
|
+
var ESCALATION_MULTIPLIER = 2;
|
|
1558
1580
|
async function sendAnthropic(args) {
|
|
1559
|
-
const { url, headers, body } = buildAnthropicRequest({
|
|
1560
|
-
model: args.model,
|
|
1561
|
-
apiKey: args.apiKey,
|
|
1562
|
-
messages: args.messages,
|
|
1563
|
-
maxTokens: args.maxTokens,
|
|
1564
|
-
temperature: args.temperature,
|
|
1565
|
-
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1566
|
-
});
|
|
1567
1581
|
const doFetch = args.fetchImpl ?? globalThis.fetch;
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1582
|
+
let maxTokens = args.maxTokens;
|
|
1583
|
+
let result = null;
|
|
1584
|
+
let totalAttempts = 0;
|
|
1585
|
+
for (let escalation = 0; escalation <= MAX_TOKENS_ESCALATIONS; escalation += 1) {
|
|
1586
|
+
const { url, headers, body } = buildAnthropicRequest({
|
|
1587
|
+
model: args.model,
|
|
1588
|
+
apiKey: args.apiKey,
|
|
1589
|
+
messages: args.messages,
|
|
1590
|
+
maxTokens,
|
|
1591
|
+
temperature: args.temperature,
|
|
1592
|
+
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1593
|
+
});
|
|
1594
|
+
const init = {
|
|
1595
|
+
method: "POST",
|
|
1596
|
+
headers,
|
|
1597
|
+
body: JSON.stringify(body)
|
|
1598
|
+
};
|
|
1599
|
+
if (args.signal) init.signal = args.signal;
|
|
1600
|
+
let stopReason;
|
|
1601
|
+
const attemptOnce = async () => {
|
|
1602
|
+
let respLike;
|
|
1584
1603
|
try {
|
|
1585
|
-
|
|
1604
|
+
respLike = await doFetch(url, init);
|
|
1586
1605
|
} catch (e) {
|
|
1587
|
-
throw new ProviderError("
|
|
1606
|
+
throw new ProviderError("network", `anthropic: fetch failed: ${e.message}`);
|
|
1588
1607
|
}
|
|
1589
|
-
const
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1608
|
+
const status = respLike.status;
|
|
1609
|
+
if (status >= 200 && status < 300) {
|
|
1610
|
+
let parsed;
|
|
1611
|
+
try {
|
|
1612
|
+
parsed = await respLike.json();
|
|
1613
|
+
} catch (e) {
|
|
1614
|
+
throw new ProviderError("parse", `anthropic: response body not JSON: ${e.message}`);
|
|
1615
|
+
}
|
|
1616
|
+
const { text, usage, stopReason: sr } = parseAnthropicResponse({
|
|
1617
|
+
resp: parsed,
|
|
1618
|
+
model: args.model,
|
|
1619
|
+
purpose: args.purpose ?? "worker"
|
|
1620
|
+
});
|
|
1621
|
+
stopReason = sr;
|
|
1622
|
+
return { text, attempts: 1, usage: applyPricing(usage, args.pricing) };
|
|
1623
|
+
}
|
|
1624
|
+
const bodyText = await respLike.text().catch(() => "");
|
|
1625
|
+
throw httpFailureToProviderError("anthropic", status, bodyText, parseRetryAfter(respLike), args.model);
|
|
1626
|
+
};
|
|
1627
|
+
await acquireRateLimit("anthropic", args.signal ? { signal: args.signal } : void 0);
|
|
1628
|
+
result = await sendWithRetry(attemptOnce, resolveRetryConfig(), args.signal);
|
|
1629
|
+
totalAttempts += result.attempts;
|
|
1630
|
+
if (escalation >= MAX_TOKENS_ESCALATIONS || !isEmptyDueToMaxTokens(result.text, stopReason)) {
|
|
1631
|
+
break;
|
|
1595
1632
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
};
|
|
1599
|
-
await acquireRateLimit("anthropic", args.signal ? { signal: args.signal } : void 0);
|
|
1600
|
-
return sendWithRetry(attemptOnce, resolveRetryConfig(), args.signal);
|
|
1633
|
+
maxTokens *= ESCALATION_MULTIPLIER;
|
|
1634
|
+
}
|
|
1635
|
+
return { ...result, attempts: totalAttempts };
|
|
1601
1636
|
}
|
|
1602
1637
|
|
|
1603
1638
|
// src/providers/gemini.ts
|
|
@@ -1990,12 +2025,20 @@ function detectStalePins(env) {
|
|
|
1990
2025
|
}
|
|
1991
2026
|
return out;
|
|
1992
2027
|
}
|
|
2028
|
+
function parseFallbackModels(raw) {
|
|
2029
|
+
if (!raw) return [];
|
|
2030
|
+
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2031
|
+
}
|
|
2032
|
+
function fallbackModelsFor(env, provider) {
|
|
2033
|
+
const envVar = MODEL_ENV_VARS[provider];
|
|
2034
|
+
return envVar ? parseFallbackModels(env[`${envVar}_FALLBACKS`]) : [];
|
|
2035
|
+
}
|
|
1993
2036
|
function buildProviders(opts) {
|
|
1994
2037
|
const out = {};
|
|
1995
2038
|
const anthropicKey = opts.env["ANTHROPIC_API_KEY"];
|
|
1996
2039
|
if (anthropicKey) {
|
|
1997
2040
|
const model = opts.env["ANTHROPIC_MODEL"] ?? DEFAULT_MODELS.anthropic;
|
|
1998
|
-
out["anthropic"] = makeAnthropicProvider(model, anthropicKey, opts);
|
|
2041
|
+
out["anthropic"] = makeAnthropicProvider(model, anthropicKey, opts, fallbackModelsFor(opts.env, "anthropic"));
|
|
1999
2042
|
}
|
|
2000
2043
|
const openAiCompatSpec = [
|
|
2001
2044
|
{ name: "openai", keyEnv: "OPENAI_API_KEY", modelEnv: "OPENAI_MODEL", defaultModel: DEFAULT_MODELS["openai"] },
|
|
@@ -2010,19 +2053,20 @@ function buildProviders(opts) {
|
|
|
2010
2053
|
const apiKey = opts.env[s.keyEnv];
|
|
2011
2054
|
if (!apiKey) continue;
|
|
2012
2055
|
const model = opts.env[s.modelEnv] ?? s.defaultModel;
|
|
2013
|
-
out[s.name] = makeOpenAICompatibleProvider(s.name, model, apiKey, opts);
|
|
2056
|
+
out[s.name] = makeOpenAICompatibleProvider(s.name, model, apiKey, opts, fallbackModelsFor(opts.env, s.name));
|
|
2014
2057
|
}
|
|
2015
2058
|
const geminiKey = opts.env["GEMINI_API_KEY"];
|
|
2016
2059
|
if (geminiKey) {
|
|
2017
2060
|
const model = opts.env["GEMINI_MODEL"] ?? DEFAULT_MODELS.gemini;
|
|
2018
|
-
out["gemini"] = makeGeminiProvider(model, geminiKey, opts);
|
|
2061
|
+
out["gemini"] = makeGeminiProvider(model, geminiKey, opts, fallbackModelsFor(opts.env, "gemini"));
|
|
2019
2062
|
}
|
|
2020
2063
|
return out;
|
|
2021
2064
|
}
|
|
2022
|
-
function makeAnthropicProvider(model, apiKey, opts) {
|
|
2065
|
+
function makeAnthropicProvider(model, apiKey, opts, fallbackModels = []) {
|
|
2023
2066
|
return {
|
|
2024
2067
|
name: "anthropic",
|
|
2025
2068
|
model,
|
|
2069
|
+
fallbackModels,
|
|
2026
2070
|
send: async (args) => {
|
|
2027
2071
|
const sendOpts = {
|
|
2028
2072
|
...args,
|
|
@@ -2035,11 +2079,12 @@ function makeAnthropicProvider(model, apiKey, opts) {
|
|
|
2035
2079
|
}
|
|
2036
2080
|
};
|
|
2037
2081
|
}
|
|
2038
|
-
function makeOpenAICompatibleProvider(name, model, apiKey, opts) {
|
|
2082
|
+
function makeOpenAICompatibleProvider(name, model, apiKey, opts, fallbackModels = []) {
|
|
2039
2083
|
const url = OPENAI_COMPAT_DEFAULT_URLS[name];
|
|
2040
2084
|
return {
|
|
2041
2085
|
name,
|
|
2042
2086
|
model,
|
|
2087
|
+
fallbackModels,
|
|
2043
2088
|
send: async (args) => {
|
|
2044
2089
|
const sendOpts = {
|
|
2045
2090
|
...args,
|
|
@@ -2054,10 +2099,11 @@ function makeOpenAICompatibleProvider(name, model, apiKey, opts) {
|
|
|
2054
2099
|
}
|
|
2055
2100
|
};
|
|
2056
2101
|
}
|
|
2057
|
-
function makeGeminiProvider(model, apiKey, opts) {
|
|
2102
|
+
function makeGeminiProvider(model, apiKey, opts, fallbackModels = []) {
|
|
2058
2103
|
return {
|
|
2059
2104
|
name: "gemini",
|
|
2060
2105
|
model,
|
|
2106
|
+
fallbackModels,
|
|
2061
2107
|
send: async (args) => {
|
|
2062
2108
|
const sendOpts = {
|
|
2063
2109
|
...args,
|
|
@@ -2208,7 +2254,7 @@ import { z } from "zod";
|
|
|
2208
2254
|
// src/server-meta.ts
|
|
2209
2255
|
init_esm_shims();
|
|
2210
2256
|
var SERVER_NAME = "crosscheck-agent";
|
|
2211
|
-
var SERVER_VERSION = true ? "0.2.
|
|
2257
|
+
var SERVER_VERSION = true ? "0.2.15" : "0.0.0-dev";
|
|
2212
2258
|
|
|
2213
2259
|
// src/tools/audit.ts
|
|
2214
2260
|
init_esm_shims();
|
|
@@ -2870,6 +2916,55 @@ function operatorCeiling(purpose, provider) {
|
|
|
2870
2916
|
return null;
|
|
2871
2917
|
}
|
|
2872
2918
|
|
|
2919
|
+
// src/core/model-fallback.ts
|
|
2920
|
+
init_esm_shims();
|
|
2921
|
+
|
|
2922
|
+
// src/core/retarget.ts
|
|
2923
|
+
init_esm_shims();
|
|
2924
|
+
function retargetProvider(p, newModel) {
|
|
2925
|
+
if (p.model === newModel) return p;
|
|
2926
|
+
return {
|
|
2927
|
+
name: p.name,
|
|
2928
|
+
model: newModel,
|
|
2929
|
+
send: (args) => p.send({ ...args, modelOverride: newModel })
|
|
2930
|
+
};
|
|
2931
|
+
}
|
|
2932
|
+
async function loadProviderWeights(storage, names) {
|
|
2933
|
+
const out = {};
|
|
2934
|
+
for (const raw of names) {
|
|
2935
|
+
const name = raw.toLowerCase();
|
|
2936
|
+
if (name in out) continue;
|
|
2937
|
+
const row = await storage.getProviderStats(name);
|
|
2938
|
+
if (!row) {
|
|
2939
|
+
out[name] = 0.5;
|
|
2940
|
+
continue;
|
|
2941
|
+
}
|
|
2942
|
+
const total = row.wins + row.losses + row.abstains;
|
|
2943
|
+
out[name] = total <= 0 ? 0.5 : (row.wins + 0.5 * row.abstains) / total;
|
|
2944
|
+
}
|
|
2945
|
+
return out;
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
// src/core/model-fallback.ts
|
|
2949
|
+
async function sendWithModelFallback(provider, args) {
|
|
2950
|
+
const chain = [provider.model, ...provider.fallbackModels ?? []];
|
|
2951
|
+
let lastErr;
|
|
2952
|
+
for (let i = 0; i < chain.length; i += 1) {
|
|
2953
|
+
const candidate = chain[i];
|
|
2954
|
+
const p = i === 0 ? provider : retargetProvider(provider, candidate);
|
|
2955
|
+
try {
|
|
2956
|
+
const result = await p.send(args);
|
|
2957
|
+
return { result, modelUsed: candidate };
|
|
2958
|
+
} catch (e) {
|
|
2959
|
+
lastErr = e;
|
|
2960
|
+
const isModelAccessFailure2 = e instanceof ProviderError && e.modelAccessFailure;
|
|
2961
|
+
const hasMoreCandidates = i < chain.length - 1;
|
|
2962
|
+
if (!isModelAccessFailure2 || !hasMoreCandidates) throw e;
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
throw lastErr;
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2873
2968
|
// src/core/structured.ts
|
|
2874
2969
|
async function requestStructured(provider, baseMessages, schema, opts) {
|
|
2875
2970
|
const maxRetries = opts.maxRetries ?? 1;
|
|
@@ -2948,7 +3043,7 @@ async function askOne(provider, messages, opts) {
|
|
|
2948
3043
|
const ceiling = operatorCeiling(opts.purpose, provider.name);
|
|
2949
3044
|
if (ceiling !== null && ceiling < maxTokens) maxTokens = ceiling;
|
|
2950
3045
|
try {
|
|
2951
|
-
const r = await provider
|
|
3046
|
+
const { result: r, modelUsed } = await sendWithModelFallback(provider, {
|
|
2952
3047
|
messages,
|
|
2953
3048
|
maxTokens,
|
|
2954
3049
|
temperature: opts.temperature,
|
|
@@ -2961,7 +3056,10 @@ async function askOne(provider, messages, opts) {
|
|
|
2961
3056
|
const cpuMs = Math.trunc((cpu.user + cpu.system) / 1e3);
|
|
2962
3057
|
return {
|
|
2963
3058
|
provider: provider.name,
|
|
2964
|
-
model
|
|
3059
|
+
// modelUsed reflects whichever model actually answered — the
|
|
3060
|
+
// primary, or a fallback if one was needed. Equivalent to the old
|
|
3061
|
+
// `provider.model` whenever no fallback occurred.
|
|
3062
|
+
model: modelUsed,
|
|
2965
3063
|
response: r.text,
|
|
2966
3064
|
attempts: r.attempts,
|
|
2967
3065
|
usage: r.usage,
|
|
@@ -3682,32 +3780,6 @@ function numberOrNull(v) {
|
|
|
3682
3780
|
// src/tools/audit.ts
|
|
3683
3781
|
import { performance as performance2 } from "perf_hooks";
|
|
3684
3782
|
|
|
3685
|
-
// src/core/retarget.ts
|
|
3686
|
-
init_esm_shims();
|
|
3687
|
-
function retargetProvider(p, newModel) {
|
|
3688
|
-
if (p.model === newModel) return p;
|
|
3689
|
-
return {
|
|
3690
|
-
name: p.name,
|
|
3691
|
-
model: newModel,
|
|
3692
|
-
send: (args) => p.send({ ...args, modelOverride: newModel })
|
|
3693
|
-
};
|
|
3694
|
-
}
|
|
3695
|
-
async function loadProviderWeights(storage, names) {
|
|
3696
|
-
const out = {};
|
|
3697
|
-
for (const raw of names) {
|
|
3698
|
-
const name = raw.toLowerCase();
|
|
3699
|
-
if (name in out) continue;
|
|
3700
|
-
const row = await storage.getProviderStats(name);
|
|
3701
|
-
if (!row) {
|
|
3702
|
-
out[name] = 0.5;
|
|
3703
|
-
continue;
|
|
3704
|
-
}
|
|
3705
|
-
const total = row.wins + row.losses + row.abstains;
|
|
3706
|
-
out[name] = total <= 0 ? 0.5 : (row.wins + 0.5 * row.abstains) / total;
|
|
3707
|
-
}
|
|
3708
|
-
return out;
|
|
3709
|
-
}
|
|
3710
|
-
|
|
3711
3783
|
// src/core/co-reason.ts
|
|
3712
3784
|
init_esm_shims();
|
|
3713
3785
|
var CO_REASON_MODEL = "gpt-5.6";
|
|
@@ -12519,7 +12591,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
12519
12591
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
12520
12592
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
12521
12593
|
function engineVersion() {
|
|
12522
|
-
return true ? "0.2.
|
|
12594
|
+
return true ? "0.2.15" : "0.0.0-dev";
|
|
12523
12595
|
}
|
|
12524
12596
|
function defaultUpdateCachePath() {
|
|
12525
12597
|
const base = process.env["CROSSCHECK_DATA_DIR"] || path10.join(os.homedir() || os.tmpdir(), ".crosscheck");
|