@algosuite/vo-mcp 0.2.0-beta.27 → 0.2.0-beta.28
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/agent-auth-probe-cli.mjs +10 -8
- package/dist/runner-cli.js +24 -103
- package/dist/runner-cli.js.map +4 -4
- package/dist/set-key-cli.js +38 -2
- package/dist/set-key-cli.js.map +2 -2
- package/package.json +1 -1
|
@@ -190,7 +190,8 @@ function wantsKey(env) {
|
|
|
190
190
|
return isTruthyFlag(env[CLAUDE_PREFER_KEY_ENV]) || isTruthyFlag(env[PREFER_KEY_ENV]);
|
|
191
191
|
}
|
|
192
192
|
function withAnthropicKey(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
|
|
193
|
-
|
|
193
|
+
const preferKey = wantsKey(baseEnv);
|
|
194
|
+
if (!preferKey && wantsLogin(baseEnv)) {
|
|
194
195
|
const next = { ...baseEnv };
|
|
195
196
|
delete next.ANTHROPIC_API_KEY;
|
|
196
197
|
return next;
|
|
@@ -198,19 +199,20 @@ function withAnthropicKey(baseEnv = {}, { getKey = getAnthropicKey, probeLogin =
|
|
|
198
199
|
if (baseEnv.ANTHROPIC_API_KEY) return { ...baseEnv };
|
|
199
200
|
const key = getKey();
|
|
200
201
|
if (!key) return { ...baseEnv };
|
|
201
|
-
if (!
|
|
202
|
+
if (!preferKey && probeLogin() === true) return { ...baseEnv };
|
|
202
203
|
return { ...baseEnv, ANTHROPIC_API_KEY: key };
|
|
203
204
|
}
|
|
204
205
|
function claudeCostBasis(env = process.env) {
|
|
205
206
|
return String(env.ANTHROPIC_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
|
|
206
207
|
}
|
|
207
208
|
function describeAnthropicAuthSource(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
|
|
208
|
-
|
|
209
|
+
const preferKey = wantsKey(baseEnv);
|
|
210
|
+
if (!preferKey && wantsLogin(baseEnv)) {
|
|
209
211
|
return "claude auth login (VO_RUNNER_PREFER_LOGIN set \u2014 any API key ignored)";
|
|
210
212
|
}
|
|
211
213
|
if (baseEnv.ANTHROPIC_API_KEY) return "ANTHROPIC_API_KEY from environment";
|
|
212
214
|
if (!getKey()) return "claude auth login session (no API key set)";
|
|
213
|
-
if (
|
|
215
|
+
if (preferKey) {
|
|
214
216
|
return "ANTHROPIC_API_KEY from OS keychain (VO_RUNNER_PREFER_KEY set \u2014 subscription ignored)";
|
|
215
217
|
}
|
|
216
218
|
if (probeLogin() === true) {
|
|
@@ -1347,7 +1349,7 @@ var OpenAICompatibleRunner = class {
|
|
|
1347
1349
|
buildArgs(opts = {}) {
|
|
1348
1350
|
void opts;
|
|
1349
1351
|
throw new Error(
|
|
1350
|
-
"OpenAI-compatible full-repository coding is disabled. Use an explicit sanitized task capsule through the AlgoSuite Model Firewall."
|
|
1352
|
+
"OpenAI-compatible full-repository coding is disabled. The `oai` runner lane is RETIRED (PR #8742) and executes nothing. Set VO_CODE_RUNNER_AGENT to claude, codex, cursor, local, or meta. Use an explicit sanitized task capsule through the AlgoSuite Model Firewall."
|
|
1351
1353
|
);
|
|
1352
1354
|
}
|
|
1353
1355
|
/** Codex JSONL events map identically → reuse the proven parser. */
|
|
@@ -1370,14 +1372,14 @@ var OpenAICompatibleRunner = class {
|
|
|
1370
1372
|
describeAuth(env = process.env) {
|
|
1371
1373
|
const hasKey = Boolean(String(env[OAI_API_KEY_ENV] || "").trim());
|
|
1372
1374
|
const baseUrl = resolveOaiBaseUrl(env);
|
|
1373
|
-
return `oai-compat endpoint=${baseUrl || "<unset>"} key=${hasKey ? "set" : "MISSING"}`;
|
|
1375
|
+
return `oai-compat RETIRED endpoint=${baseUrl || "<unset>"} key=${hasKey ? "set" : "MISSING"}`;
|
|
1374
1376
|
}
|
|
1375
|
-
/**
|
|
1377
|
+
/** Always unavailable: the lane is retired, so nothing can authenticate it. */
|
|
1376
1378
|
async checkAuth() {
|
|
1377
1379
|
return {
|
|
1378
1380
|
installed: false,
|
|
1379
1381
|
authenticated: false,
|
|
1380
|
-
message: "OpenAI-compatible coding is disabled
|
|
1382
|
+
message: "the `oai` lane is RETIRED (PR #8742); OpenAI-compatible coding is disabled \u2014 sanitized Model Firewall task capsules only"
|
|
1381
1383
|
};
|
|
1382
1384
|
}
|
|
1383
1385
|
};
|
package/dist/runner-cli.js
CHANGED
|
@@ -3033,7 +3033,8 @@ function wantsKey(env2) {
|
|
|
3033
3033
|
return isTruthyFlag(env2[CLAUDE_PREFER_KEY_ENV]) || isTruthyFlag(env2[PREFER_KEY_ENV]);
|
|
3034
3034
|
}
|
|
3035
3035
|
function withAnthropicKey(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
|
|
3036
|
-
|
|
3036
|
+
const preferKey = wantsKey(baseEnv);
|
|
3037
|
+
if (!preferKey && wantsLogin(baseEnv)) {
|
|
3037
3038
|
const next = { ...baseEnv };
|
|
3038
3039
|
delete next.ANTHROPIC_API_KEY;
|
|
3039
3040
|
return next;
|
|
@@ -3041,19 +3042,20 @@ function withAnthropicKey(baseEnv = {}, { getKey = getAnthropicKey, probeLogin =
|
|
|
3041
3042
|
if (baseEnv.ANTHROPIC_API_KEY) return { ...baseEnv };
|
|
3042
3043
|
const key = getKey();
|
|
3043
3044
|
if (!key) return { ...baseEnv };
|
|
3044
|
-
if (!
|
|
3045
|
+
if (!preferKey && probeLogin() === true) return { ...baseEnv };
|
|
3045
3046
|
return { ...baseEnv, ANTHROPIC_API_KEY: key };
|
|
3046
3047
|
}
|
|
3047
3048
|
function claudeCostBasis(env2 = process.env) {
|
|
3048
3049
|
return String(env2.ANTHROPIC_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
|
|
3049
3050
|
}
|
|
3050
3051
|
function describeAnthropicAuthSource(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
|
|
3051
|
-
|
|
3052
|
+
const preferKey = wantsKey(baseEnv);
|
|
3053
|
+
if (!preferKey && wantsLogin(baseEnv)) {
|
|
3052
3054
|
return "claude auth login (VO_RUNNER_PREFER_LOGIN set \u2014 any API key ignored)";
|
|
3053
3055
|
}
|
|
3054
3056
|
if (baseEnv.ANTHROPIC_API_KEY) return "ANTHROPIC_API_KEY from environment";
|
|
3055
3057
|
if (!getKey()) return "claude auth login session (no API key set)";
|
|
3056
|
-
if (
|
|
3058
|
+
if (preferKey) {
|
|
3057
3059
|
return "ANTHROPIC_API_KEY from OS keychain (VO_RUNNER_PREFER_KEY set \u2014 subscription ignored)";
|
|
3058
3060
|
}
|
|
3059
3061
|
if (probeLogin() === true) {
|
|
@@ -3068,13 +3070,13 @@ function augmentAuthError(summary) {
|
|
|
3068
3070
|
\u21B3 Anthropic auth failed on the runner. The \`claude\` CLI is a SEPARATE install/login from the Claude Desktop app and the Claude Code IDE extension \u2014 signing into those does NOT authenticate it. Fix: run \`claude auth login\` (Claude subscription) on the runner machine, or clear any stale ANTHROPIC_API_KEY (env / OS keychain / .env.local) and set VO_RUNNER_PREFER_LOGIN=1 \u2014 then restart the runner. Verify with \`claude -p "say hi"\`.`;
|
|
3069
3071
|
}
|
|
3070
3072
|
function probeClaudeLoginState({
|
|
3071
|
-
spawn:
|
|
3073
|
+
spawn: spawn5 = spawnSync2,
|
|
3072
3074
|
buildWindowsLaunch = buildWindowsClaudeLaunch,
|
|
3073
3075
|
platform = process.platform
|
|
3074
3076
|
} = {}) {
|
|
3075
3077
|
try {
|
|
3076
3078
|
const launch = platform === "win32" ? buildWindowsLaunch({ bin: "claude", args: ["auth", "status"] }) : { bin: "claude", args: ["auth", "status"], spawnOptions: { windowsHide: true } };
|
|
3077
|
-
const st =
|
|
3079
|
+
const st = spawn5(launch.bin, launch.args, { ...launch.spawnOptions, timeout: 5e3, encoding: "utf8" });
|
|
3078
3080
|
const parsed = JSON.parse(String(st.stdout || "").trim() || "{}");
|
|
3079
3081
|
return typeof parsed.loggedIn === "boolean" ? parsed.loggedIn : null;
|
|
3080
3082
|
} catch {
|
|
@@ -3327,11 +3329,11 @@ import { spawnSync as spawnSync4 } from "node:child_process";
|
|
|
3327
3329
|
function terminateAgentProcessTree({
|
|
3328
3330
|
child,
|
|
3329
3331
|
platform = process.platform,
|
|
3330
|
-
spawn:
|
|
3332
|
+
spawn: spawn5 = spawnSync4
|
|
3331
3333
|
} = {}) {
|
|
3332
3334
|
if (!child || !Number.isInteger(child.pid) || child.pid <= 0) return false;
|
|
3333
3335
|
if (platform === "win32") {
|
|
3334
|
-
const result =
|
|
3336
|
+
const result = spawn5("taskkill", ["/PID", String(child.pid), "/T", "/F"], {
|
|
3335
3337
|
windowsHide: true,
|
|
3336
3338
|
stdio: "ignore",
|
|
3337
3339
|
timeout: 15e3
|
|
@@ -3507,11 +3509,11 @@ function windowsSystemRoot(env2 = process.env) {
|
|
|
3507
3509
|
function windowsPowershellExe(env2 = process.env) {
|
|
3508
3510
|
return path11.join(windowsSystemRoot(env2), "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
3509
3511
|
}
|
|
3510
|
-
function listProcessCreationTimes({ platform = process.platform, spawn:
|
|
3512
|
+
function listProcessCreationTimes({ platform = process.platform, spawn: spawn5 = spawnSync5, env: env2 = process.env, warn = console.warn } = {}) {
|
|
3511
3513
|
const map = /* @__PURE__ */ new Map();
|
|
3512
3514
|
if (platform === "win32") {
|
|
3513
3515
|
const ps = "Get-CimInstance Win32_Process | ForEach-Object { '{0} {1}' -f $_.ProcessId, (([DateTimeOffset]$_.CreationDate.ToUniversalTime()).ToUnixTimeMilliseconds()) }";
|
|
3514
|
-
const result2 =
|
|
3516
|
+
const result2 = spawn5(windowsPowershellExe(env2), ["-NoProfile", "-NonInteractive", "-Command", ps], {
|
|
3515
3517
|
windowsHide: true,
|
|
3516
3518
|
encoding: "utf8",
|
|
3517
3519
|
timeout: 2e4,
|
|
@@ -3527,7 +3529,7 @@ function listProcessCreationTimes({ platform = process.platform, spawn: spawn6 =
|
|
|
3527
3529
|
}
|
|
3528
3530
|
return map;
|
|
3529
3531
|
}
|
|
3530
|
-
const result =
|
|
3532
|
+
const result = spawn5("ps", ["-eo", "pid=,lstart="], { encoding: "utf8", timeout: 2e4, maxBuffer: 32 * 1024 * 1024 });
|
|
3531
3533
|
if (result.error || result.status !== 0 || typeof result.stdout !== "string") {
|
|
3532
3534
|
warn(`[orphan-reaper] process enumeration failed (${result.error ? result.error.message : `ps exit ${result.status}`}); reaping nothing this cycle`);
|
|
3533
3535
|
return map;
|
|
@@ -3547,11 +3549,11 @@ function parsePosixPsLine(line) {
|
|
|
3547
3549
|
if (!Number.isInteger(pid) || pid <= 0 || !Number.isFinite(when)) return null;
|
|
3548
3550
|
return { pid, creationMs: when };
|
|
3549
3551
|
}
|
|
3550
|
-
function killProcessTree(pid, { platform = process.platform, spawn:
|
|
3552
|
+
function killProcessTree(pid, { platform = process.platform, spawn: spawn5 = spawnSync5, env: env2 = process.env } = {}) {
|
|
3551
3553
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
3552
3554
|
if (platform === "win32") {
|
|
3553
3555
|
const taskkill = path11.join(windowsSystemRoot(env2), "System32", "taskkill.exe");
|
|
3554
|
-
const r =
|
|
3556
|
+
const r = spawn5(taskkill, ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore", timeout: 15e3 });
|
|
3555
3557
|
return !r.error && r.status === 0;
|
|
3556
3558
|
}
|
|
3557
3559
|
try {
|
|
@@ -4451,8 +4453,8 @@ var init_codex_runner = __esm({
|
|
|
4451
4453
|
CODEX_PREFER_LOGIN_ENV = "VO_RUNNER_CODEX_PREFER_LOGIN";
|
|
4452
4454
|
LEGACY_PREFER_LOGIN_ENV = "VO_RUNNER_PREFER_LOGIN";
|
|
4453
4455
|
CodexRunner = class {
|
|
4454
|
-
constructor({ spawn:
|
|
4455
|
-
this.spawn =
|
|
4456
|
+
constructor({ spawn: spawn5 = spawnSync6, resolveBinary = resolveCodexBinary, env: env2 = process.env } = {}) {
|
|
4457
|
+
this.spawn = spawn5;
|
|
4456
4458
|
this.resolveBinary = resolveBinary;
|
|
4457
4459
|
this.env = env2;
|
|
4458
4460
|
}
|
|
@@ -4821,12 +4823,12 @@ var init_local_model_runner = __esm({
|
|
|
4821
4823
|
LOCAL_MODEL_RE = new RegExp("^[A-Za-z0-9][A-Za-z0-9._/:-]{0,127}$");
|
|
4822
4824
|
LocalModelRunner = class {
|
|
4823
4825
|
constructor({
|
|
4824
|
-
spawn:
|
|
4826
|
+
spawn: spawn5 = null,
|
|
4825
4827
|
resolveBinary = resolveCodexBinary,
|
|
4826
4828
|
env: env2 = process.env,
|
|
4827
4829
|
fetchImpl = globalThis.fetch
|
|
4828
4830
|
} = {}) {
|
|
4829
|
-
this.spawn =
|
|
4831
|
+
this.spawn = spawn5;
|
|
4830
4832
|
this.resolveBinary = resolveBinary;
|
|
4831
4833
|
this.env = env2;
|
|
4832
4834
|
this.fetchImpl = fetchImpl;
|
|
@@ -5012,7 +5014,7 @@ var init_openai_compatible_runner = __esm({
|
|
|
5012
5014
|
buildArgs(opts = {}) {
|
|
5013
5015
|
void opts;
|
|
5014
5016
|
throw new Error(
|
|
5015
|
-
"OpenAI-compatible full-repository coding is disabled. Use an explicit sanitized task capsule through the AlgoSuite Model Firewall."
|
|
5017
|
+
"OpenAI-compatible full-repository coding is disabled. The `oai` runner lane is RETIRED (PR #8742) and executes nothing. Set VO_CODE_RUNNER_AGENT to claude, codex, cursor, local, or meta. Use an explicit sanitized task capsule through the AlgoSuite Model Firewall."
|
|
5016
5018
|
);
|
|
5017
5019
|
}
|
|
5018
5020
|
/** Codex JSONL events map identically → reuse the proven parser. */
|
|
@@ -5035,14 +5037,14 @@ var init_openai_compatible_runner = __esm({
|
|
|
5035
5037
|
describeAuth(env2 = process.env) {
|
|
5036
5038
|
const hasKey = Boolean(String(env2[OAI_API_KEY_ENV] || "").trim());
|
|
5037
5039
|
const baseUrl = resolveOaiBaseUrl(env2);
|
|
5038
|
-
return `oai-compat endpoint=${baseUrl || "<unset>"} key=${hasKey ? "set" : "MISSING"}`;
|
|
5040
|
+
return `oai-compat RETIRED endpoint=${baseUrl || "<unset>"} key=${hasKey ? "set" : "MISSING"}`;
|
|
5039
5041
|
}
|
|
5040
|
-
/**
|
|
5042
|
+
/** Always unavailable: the lane is retired, so nothing can authenticate it. */
|
|
5041
5043
|
async checkAuth() {
|
|
5042
5044
|
return {
|
|
5043
5045
|
installed: false,
|
|
5044
5046
|
authenticated: false,
|
|
5045
|
-
message: "OpenAI-compatible coding is disabled
|
|
5047
|
+
message: "the `oai` lane is RETIRED (PR #8742); OpenAI-compatible coding is disabled \u2014 sanitized Model Firewall task capsules only"
|
|
5046
5048
|
};
|
|
5047
5049
|
}
|
|
5048
5050
|
};
|
|
@@ -7731,83 +7733,6 @@ var init_codex = __esm({
|
|
|
7731
7733
|
}
|
|
7732
7734
|
});
|
|
7733
7735
|
|
|
7734
|
-
// ../../scripts/virtual-office/code-runner/account-usage/copilot.mjs
|
|
7735
|
-
import { spawn as spawn5 } from "node:child_process";
|
|
7736
|
-
function parseCopilotUsage(body, { now = () => Date.now() } = {}) {
|
|
7737
|
-
if (!body || typeof body !== "object") return null;
|
|
7738
|
-
const snapshots = body.quota_snapshots;
|
|
7739
|
-
if (!snapshots || typeof snapshots !== "object") return null;
|
|
7740
|
-
const bucket = snapshots[METERED_BUCKET];
|
|
7741
|
-
if (!bucket || typeof bucket !== "object") return null;
|
|
7742
|
-
if (bucket.unlimited === true || bucket.has_quota === false) return null;
|
|
7743
|
-
const remaining = clampPct(bucket.percent_remaining);
|
|
7744
|
-
if (remaining === null) return null;
|
|
7745
|
-
const resetDate = typeof body.quota_reset_date === "string" ? body.quota_reset_date : null;
|
|
7746
|
-
const resetsAt = resetDate && /^\d{4}-\d{2}-\d{2}$/.test(resetDate) ? `${resetDate}T00:00:00.000Z` : null;
|
|
7747
|
-
return makeUsageRow({
|
|
7748
|
-
agent: "copilot",
|
|
7749
|
-
source: "cli",
|
|
7750
|
-
capturedAt: new Date(now()).toISOString(),
|
|
7751
|
-
// The API reports REMAINING; every row in this system stores USED.
|
|
7752
|
-
monthly: 100 - remaining,
|
|
7753
|
-
monthlyResetsAt: resetsAt,
|
|
7754
|
-
accountId: typeof body.login === "string" ? body.login : null
|
|
7755
|
-
});
|
|
7756
|
-
}
|
|
7757
|
-
function readCopilotUsage({
|
|
7758
|
-
spawnImpl = spawn5,
|
|
7759
|
-
timeoutMs = 8e3,
|
|
7760
|
-
env: env2 = process.env,
|
|
7761
|
-
now = () => Date.now()
|
|
7762
|
-
} = {}) {
|
|
7763
|
-
return new Promise((resolve2) => {
|
|
7764
|
-
let child;
|
|
7765
|
-
let settled = false;
|
|
7766
|
-
let stdout = "";
|
|
7767
|
-
const finish = (value) => {
|
|
7768
|
-
if (settled) return;
|
|
7769
|
-
settled = true;
|
|
7770
|
-
clearTimeout(timer);
|
|
7771
|
-
try {
|
|
7772
|
-
child?.kill();
|
|
7773
|
-
} catch {
|
|
7774
|
-
}
|
|
7775
|
-
resolve2(value);
|
|
7776
|
-
};
|
|
7777
|
-
const timer = setTimeout(() => finish(null), timeoutMs);
|
|
7778
|
-
try {
|
|
7779
|
-
child = spawnImpl("gh", ["api", "copilot_internal/user"], {
|
|
7780
|
-
env: env2,
|
|
7781
|
-
windowsHide: true,
|
|
7782
|
-
shell: false,
|
|
7783
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
7784
|
-
});
|
|
7785
|
-
child.on("error", () => finish(null));
|
|
7786
|
-
child.stdout?.on("data", (chunk) => {
|
|
7787
|
-
stdout += chunk.toString();
|
|
7788
|
-
});
|
|
7789
|
-
child.on("close", (code) => {
|
|
7790
|
-
if (code !== 0) return finish(null);
|
|
7791
|
-
try {
|
|
7792
|
-
finish(parseCopilotUsage(JSON.parse(stdout), { now }));
|
|
7793
|
-
} catch {
|
|
7794
|
-
finish(null);
|
|
7795
|
-
}
|
|
7796
|
-
});
|
|
7797
|
-
} catch {
|
|
7798
|
-
finish(null);
|
|
7799
|
-
}
|
|
7800
|
-
});
|
|
7801
|
-
}
|
|
7802
|
-
var METERED_BUCKET;
|
|
7803
|
-
var init_copilot = __esm({
|
|
7804
|
-
"../../scripts/virtual-office/code-runner/account-usage/copilot.mjs"() {
|
|
7805
|
-
"use strict";
|
|
7806
|
-
init_shared();
|
|
7807
|
-
METERED_BUCKET = "premium_interactions";
|
|
7808
|
-
}
|
|
7809
|
-
});
|
|
7810
|
-
|
|
7811
7736
|
// ../../scripts/virtual-office/code-runner/account-usage/index.mjs
|
|
7812
7737
|
function collectAccountUsage(opts = {}) {
|
|
7813
7738
|
const claude = readClaudeFileUsage(opts);
|
|
@@ -7816,13 +7741,11 @@ function collectAccountUsage(opts = {}) {
|
|
|
7816
7741
|
async function collectConnectedAccountUsage({
|
|
7817
7742
|
readClaude = readClaudeUsage,
|
|
7818
7743
|
readCodex = readCodexUsage,
|
|
7819
|
-
readCopilot = readCopilotUsage,
|
|
7820
7744
|
...agentOptions
|
|
7821
7745
|
} = {}) {
|
|
7822
7746
|
const settled = await Promise.allSettled([
|
|
7823
7747
|
readClaude(agentOptions),
|
|
7824
|
-
readCodex(agentOptions)
|
|
7825
|
-
readCopilot(agentOptions)
|
|
7748
|
+
readCodex(agentOptions)
|
|
7826
7749
|
]);
|
|
7827
7750
|
return settled.map((outcome) => outcome.status === "fulfilled" ? outcome.value : null).filter(Boolean);
|
|
7828
7751
|
}
|
|
@@ -7858,12 +7781,10 @@ var init_account_usage = __esm({
|
|
|
7858
7781
|
"use strict";
|
|
7859
7782
|
init_claude();
|
|
7860
7783
|
init_codex();
|
|
7861
|
-
init_copilot();
|
|
7862
7784
|
init_shared();
|
|
7863
7785
|
AGENT_USAGE_CAPABILITY = Object.freeze({
|
|
7864
7786
|
claude: Object.freeze({ five_hour: true, seven_day: true, monthly: false }),
|
|
7865
7787
|
codex: Object.freeze({ five_hour: false, seven_day: true, monthly: false }),
|
|
7866
|
-
copilot: Object.freeze({ five_hour: false, seven_day: false, monthly: true }),
|
|
7867
7788
|
cursor: Object.freeze({ five_hour: false, seven_day: false, monthly: false }),
|
|
7868
7789
|
gemini: Object.freeze({ five_hour: false, seven_day: false, monthly: false })
|
|
7869
7790
|
});
|