@algosuite/vo-mcp 0.2.0-beta.26 → 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 +111 -12
- package/dist/runner-cli.js +420 -89
- 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
package/dist/runner-cli.js
CHANGED
|
@@ -3026,23 +3026,42 @@ function isTruthyFlag(v) {
|
|
|
3026
3026
|
const s = String(v ?? "").trim().toLowerCase();
|
|
3027
3027
|
return s === "1" || s === "true" || s === "yes" || s === "on";
|
|
3028
3028
|
}
|
|
3029
|
-
function
|
|
3030
|
-
|
|
3029
|
+
function wantsLogin(env2) {
|
|
3030
|
+
return isTruthyFlag(env2[CLAUDE_PREFER_LOGIN_ENV]) || isTruthyFlag(env2[PREFER_LOGIN_ENV]);
|
|
3031
|
+
}
|
|
3032
|
+
function wantsKey(env2) {
|
|
3033
|
+
return isTruthyFlag(env2[CLAUDE_PREFER_KEY_ENV]) || isTruthyFlag(env2[PREFER_KEY_ENV]);
|
|
3034
|
+
}
|
|
3035
|
+
function withAnthropicKey(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
|
|
3036
|
+
const preferKey = wantsKey(baseEnv);
|
|
3037
|
+
if (!preferKey && wantsLogin(baseEnv)) {
|
|
3031
3038
|
const next = { ...baseEnv };
|
|
3032
3039
|
delete next.ANTHROPIC_API_KEY;
|
|
3033
3040
|
return next;
|
|
3034
3041
|
}
|
|
3035
3042
|
if (baseEnv.ANTHROPIC_API_KEY) return { ...baseEnv };
|
|
3036
3043
|
const key = getKey();
|
|
3037
|
-
|
|
3044
|
+
if (!key) return { ...baseEnv };
|
|
3045
|
+
if (!preferKey && probeLogin() === true) return { ...baseEnv };
|
|
3046
|
+
return { ...baseEnv, ANTHROPIC_API_KEY: key };
|
|
3047
|
+
}
|
|
3048
|
+
function claudeCostBasis(env2 = process.env) {
|
|
3049
|
+
return String(env2.ANTHROPIC_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
|
|
3038
3050
|
}
|
|
3039
|
-
function describeAnthropicAuthSource(baseEnv = {}, { getKey = getAnthropicKey } = {}) {
|
|
3040
|
-
|
|
3051
|
+
function describeAnthropicAuthSource(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
|
|
3052
|
+
const preferKey = wantsKey(baseEnv);
|
|
3053
|
+
if (!preferKey && wantsLogin(baseEnv)) {
|
|
3041
3054
|
return "claude auth login (VO_RUNNER_PREFER_LOGIN set \u2014 any API key ignored)";
|
|
3042
3055
|
}
|
|
3043
3056
|
if (baseEnv.ANTHROPIC_API_KEY) return "ANTHROPIC_API_KEY from environment";
|
|
3044
|
-
if (getKey()) return "
|
|
3045
|
-
|
|
3057
|
+
if (!getKey()) return "claude auth login session (no API key set)";
|
|
3058
|
+
if (preferKey) {
|
|
3059
|
+
return "ANTHROPIC_API_KEY from OS keychain (VO_RUNNER_PREFER_KEY set \u2014 subscription ignored)";
|
|
3060
|
+
}
|
|
3061
|
+
if (probeLogin() === true) {
|
|
3062
|
+
return "claude auth login session (subscription beats the stored keychain key)";
|
|
3063
|
+
}
|
|
3064
|
+
return "ANTHROPIC_API_KEY from OS keychain";
|
|
3046
3065
|
}
|
|
3047
3066
|
function augmentAuthError(summary) {
|
|
3048
3067
|
const s = String(summary ?? "");
|
|
@@ -3064,7 +3083,7 @@ function probeClaudeLoginState({
|
|
|
3064
3083
|
return null;
|
|
3065
3084
|
}
|
|
3066
3085
|
}
|
|
3067
|
-
var require2, KEY_SERVICE, KEY_ACCOUNT, _entryCtor, _loadTried, PREFER_LOGIN_ENV, CLAUDE_PREFER_LOGIN_ENV, AUTH_ERROR_RE;
|
|
3086
|
+
var require2, KEY_SERVICE, KEY_ACCOUNT, _entryCtor, _loadTried, PREFER_LOGIN_ENV, CLAUDE_PREFER_LOGIN_ENV, PREFER_KEY_ENV, CLAUDE_PREFER_KEY_ENV, AUTH_ERROR_RE;
|
|
3068
3087
|
var init_anthropic_key_store = __esm({
|
|
3069
3088
|
"../../scripts/virtual-office/code-runner/anthropic-key-store.mjs"() {
|
|
3070
3089
|
"use strict";
|
|
@@ -3075,6 +3094,8 @@ var init_anthropic_key_store = __esm({
|
|
|
3075
3094
|
_loadTried = false;
|
|
3076
3095
|
PREFER_LOGIN_ENV = "VO_RUNNER_PREFER_LOGIN";
|
|
3077
3096
|
CLAUDE_PREFER_LOGIN_ENV = "VO_RUNNER_CLAUDE_PREFER_LOGIN";
|
|
3097
|
+
PREFER_KEY_ENV = "VO_RUNNER_PREFER_KEY";
|
|
3098
|
+
CLAUDE_PREFER_KEY_ENV = "VO_RUNNER_CLAUDE_PREFER_KEY";
|
|
3078
3099
|
AUTH_ERROR_RE = /\b401\b|invalid[^.]{0,24}(authentication|credential)|authentication_error|unauthorized|not[ _-]?authenticated/i;
|
|
3079
3100
|
}
|
|
3080
3101
|
});
|
|
@@ -3734,6 +3755,46 @@ var init_claude_stream_event = __esm({
|
|
|
3734
3755
|
}
|
|
3735
3756
|
});
|
|
3736
3757
|
|
|
3758
|
+
// ../../scripts/virtual-office/code-runner/agent-auth-tier.mjs
|
|
3759
|
+
function authTierFromCostBasis(costBasis) {
|
|
3760
|
+
return COST_BASIS_TO_TIER[String(costBasis ?? "")] ?? AUTH_TIER_UNKNOWN;
|
|
3761
|
+
}
|
|
3762
|
+
function safeAuthTier(compute) {
|
|
3763
|
+
try {
|
|
3764
|
+
return normalizeAuthTier(compute());
|
|
3765
|
+
} catch {
|
|
3766
|
+
return AUTH_TIER_UNKNOWN;
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
function normalizeAuthTier(value) {
|
|
3770
|
+
return AUTH_TIERS.includes(value) ? value : AUTH_TIER_UNKNOWN;
|
|
3771
|
+
}
|
|
3772
|
+
function resolveReportedAuthTier({ authTier, installed, authenticated } = {}) {
|
|
3773
|
+
if (installed !== true || authenticated !== true) return AUTH_TIER_UNKNOWN;
|
|
3774
|
+
return normalizeAuthTier(authTier);
|
|
3775
|
+
}
|
|
3776
|
+
var AUTH_TIER_SUBSCRIPTION, AUTH_TIER_API_KEY, AUTH_TIER_LOCAL, AUTH_TIER_UNKNOWN, AUTH_TIERS, COST_BASIS_TO_TIER;
|
|
3777
|
+
var init_agent_auth_tier = __esm({
|
|
3778
|
+
"../../scripts/virtual-office/code-runner/agent-auth-tier.mjs"() {
|
|
3779
|
+
"use strict";
|
|
3780
|
+
AUTH_TIER_SUBSCRIPTION = "subscription";
|
|
3781
|
+
AUTH_TIER_API_KEY = "api_key";
|
|
3782
|
+
AUTH_TIER_LOCAL = "local";
|
|
3783
|
+
AUTH_TIER_UNKNOWN = "unknown";
|
|
3784
|
+
AUTH_TIERS = Object.freeze([
|
|
3785
|
+
AUTH_TIER_SUBSCRIPTION,
|
|
3786
|
+
AUTH_TIER_API_KEY,
|
|
3787
|
+
AUTH_TIER_LOCAL,
|
|
3788
|
+
AUTH_TIER_UNKNOWN
|
|
3789
|
+
]);
|
|
3790
|
+
COST_BASIS_TO_TIER = Object.freeze({
|
|
3791
|
+
subscription_api_equivalent: AUTH_TIER_SUBSCRIPTION,
|
|
3792
|
+
vendor_billed: AUTH_TIER_API_KEY,
|
|
3793
|
+
local_zero: AUTH_TIER_LOCAL
|
|
3794
|
+
});
|
|
3795
|
+
}
|
|
3796
|
+
});
|
|
3797
|
+
|
|
3737
3798
|
// ../../scripts/virtual-office/code-runner/cli-version-floor.mjs
|
|
3738
3799
|
function parseCliVersion(output) {
|
|
3739
3800
|
const match = /\b(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?\b/.exec(String(output ?? ""));
|
|
@@ -3803,9 +3864,22 @@ function isTimeout(probe) {
|
|
|
3803
3864
|
function notFound(probe) {
|
|
3804
3865
|
return errorCode(probe?.error) === "ENOENT";
|
|
3805
3866
|
}
|
|
3867
|
+
function resolveClaudeAuthTier({
|
|
3868
|
+
env: env2 = process.env,
|
|
3869
|
+
loggedIn = null,
|
|
3870
|
+
getStoredKey = getAnthropicKey
|
|
3871
|
+
} = {}) {
|
|
3872
|
+
return safeAuthTier(() => {
|
|
3873
|
+
const spawnEnv = withAnthropicKey(env2, { getKey: getStoredKey, probeLogin: () => loggedIn });
|
|
3874
|
+
const tier = authTierFromCostBasis(claudeCostBasis(spawnEnv));
|
|
3875
|
+
if (tier === AUTH_TIER_SUBSCRIPTION && loggedIn !== true) return AUTH_TIER_UNKNOWN;
|
|
3876
|
+
return tier;
|
|
3877
|
+
});
|
|
3878
|
+
}
|
|
3806
3879
|
async function checkClaudeAuth({
|
|
3807
3880
|
spawnVersion = spawnClaudeSync,
|
|
3808
3881
|
probeLogin = probeClaudeLoginState,
|
|
3882
|
+
getStoredKey = getAnthropicKey,
|
|
3809
3883
|
env: env2 = process.env
|
|
3810
3884
|
} = {}) {
|
|
3811
3885
|
try {
|
|
@@ -3855,6 +3929,10 @@ async function checkClaudeAuth({
|
|
|
3855
3929
|
return {
|
|
3856
3930
|
installed: true,
|
|
3857
3931
|
authenticated: true,
|
|
3932
|
+
// Dispatch-time billing signal, carried on the same probe that already
|
|
3933
|
+
// paid for the login read. Never sent for a non-authenticated result:
|
|
3934
|
+
// there is no tier without a working credential.
|
|
3935
|
+
authTier: resolveClaudeAuthTier({ env: env2, loggedIn, getStoredKey }),
|
|
3858
3936
|
message: loggedIn === true ? "claude CLI installed and logged in (claude auth status)" : "claude binary found (login state unknown \u2014 auth check is best-effort)"
|
|
3859
3937
|
};
|
|
3860
3938
|
} catch (error) {
|
|
@@ -3870,6 +3948,7 @@ var init_claude_auth_check = __esm({
|
|
|
3870
3948
|
"../../scripts/virtual-office/code-runner/claude-auth-check.mjs"() {
|
|
3871
3949
|
"use strict";
|
|
3872
3950
|
init_anthropic_key_store();
|
|
3951
|
+
init_agent_auth_tier();
|
|
3873
3952
|
init_cli_version_floor();
|
|
3874
3953
|
init_windows_claude_launch();
|
|
3875
3954
|
FIRST_VERSION_TIMEOUT_MS = 4500;
|
|
@@ -4134,7 +4213,7 @@ var init_claude_runner = __esm({
|
|
|
4134
4213
|
return withAnthropicKey(env2);
|
|
4135
4214
|
}
|
|
4136
4215
|
costBasis(env2 = process.env) {
|
|
4137
|
-
return
|
|
4216
|
+
return claudeCostBasis(env2);
|
|
4138
4217
|
}
|
|
4139
4218
|
/** Describe which Anthropic auth source the spawn will use (for runner logs). */
|
|
4140
4219
|
describeAuth(env2 = process.env) {
|
|
@@ -4369,6 +4448,7 @@ var init_codex_runner = __esm({
|
|
|
4369
4448
|
"../../scripts/virtual-office/code-runner/codex-runner.mjs"() {
|
|
4370
4449
|
"use strict";
|
|
4371
4450
|
init_agent_key_store();
|
|
4451
|
+
init_agent_auth_tier();
|
|
4372
4452
|
init_flat_token_usage();
|
|
4373
4453
|
CODEX_PREFER_LOGIN_ENV = "VO_RUNNER_CODEX_PREFER_LOGIN";
|
|
4374
4454
|
LEGACY_PREFER_LOGIN_ENV = "VO_RUNNER_PREFER_LOGIN";
|
|
@@ -4426,6 +4506,19 @@ var init_codex_runner = __esm({
|
|
|
4426
4506
|
costBasis(env2 = process.env) {
|
|
4427
4507
|
return String(env2.OPENAI_API_KEY || env2.CODEX_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
|
|
4428
4508
|
}
|
|
4509
|
+
/**
|
|
4510
|
+
* Dispatch-time billing tier for the NEXT codex spawn, from the SAME facts
|
|
4511
|
+
* checkAuth() already gathered — no extra subprocess. applyAuthEnv() is a
|
|
4512
|
+
* keychain read in this process (@napi-rs/keyring), not a spawn.
|
|
4513
|
+
*
|
|
4514
|
+
* Codex is the agent where this signal was already computed and then thrown
|
|
4515
|
+
* away: checkAuth() distinguished "API key available (no persisted ChatGPT
|
|
4516
|
+
* login)" from a real login, but only inside a `message` string that the
|
|
4517
|
+
* heartbeat schema strips before storage. This gives that fact a typed home.
|
|
4518
|
+
*/
|
|
4519
|
+
authTier(env2 = this.env) {
|
|
4520
|
+
return safeAuthTier(() => authTierFromCostBasis(this.costBasis(this.applyAuthEnv(env2))));
|
|
4521
|
+
}
|
|
4429
4522
|
/** Best-effort binary + persisted-login probe. Never throws or spends tokens. */
|
|
4430
4523
|
async checkAuth() {
|
|
4431
4524
|
try {
|
|
@@ -4459,6 +4552,7 @@ ${login.stderr || ""}`.trim();
|
|
|
4459
4552
|
installed: true,
|
|
4460
4553
|
authenticated: true,
|
|
4461
4554
|
...versionField,
|
|
4555
|
+
authTier: this.authTier(),
|
|
4462
4556
|
message: "codex API key available (no persisted ChatGPT login)"
|
|
4463
4557
|
};
|
|
4464
4558
|
}
|
|
@@ -4473,6 +4567,7 @@ ${login.stderr || ""}`.trim();
|
|
|
4473
4567
|
installed: true,
|
|
4474
4568
|
authenticated: true,
|
|
4475
4569
|
...versionField,
|
|
4570
|
+
authTier: this.authTier(),
|
|
4476
4571
|
message: output || "codex login status succeeded"
|
|
4477
4572
|
};
|
|
4478
4573
|
} catch (err) {
|
|
@@ -4539,6 +4634,7 @@ var init_cursor_runner = __esm({
|
|
|
4539
4634
|
"../../scripts/virtual-office/code-runner/cursor-runner.mjs"() {
|
|
4540
4635
|
"use strict";
|
|
4541
4636
|
init_agent_key_store();
|
|
4637
|
+
init_agent_auth_tier();
|
|
4542
4638
|
init_flat_token_usage();
|
|
4543
4639
|
CursorRunner = class {
|
|
4544
4640
|
get binary() {
|
|
@@ -4583,6 +4679,16 @@ var init_cursor_runner = __esm({
|
|
|
4583
4679
|
costBasis(env2 = process.env) {
|
|
4584
4680
|
return env2.CURSOR_API_KEY ? "vendor_billed" : "unknown";
|
|
4585
4681
|
}
|
|
4682
|
+
/**
|
|
4683
|
+
* Dispatch-time billing tier. Inherits costBasis()'s deliberate refusal to
|
|
4684
|
+
* guess: a prior interactive `cursor-agent login` has undocumented
|
|
4685
|
+
* subscription semantics, so it reports 'unknown' rather than claiming a
|
|
4686
|
+
* flat-cost seat the runner cannot actually prove. Keychain read only — the
|
|
4687
|
+
* heartbeat never pays for a subprocess to answer this.
|
|
4688
|
+
*/
|
|
4689
|
+
authTier(env2 = process.env) {
|
|
4690
|
+
return safeAuthTier(() => authTierFromCostBasis(this.costBasis(this.applyAuthEnv(env2))));
|
|
4691
|
+
}
|
|
4586
4692
|
/** Best-effort: is `cursor-agent` on PATH? Never throws. */
|
|
4587
4693
|
async checkAuth() {
|
|
4588
4694
|
try {
|
|
@@ -4608,6 +4714,7 @@ var init_cursor_runner = __esm({
|
|
|
4608
4714
|
return {
|
|
4609
4715
|
installed: true,
|
|
4610
4716
|
authenticated: true,
|
|
4717
|
+
authTier: this.authTier(),
|
|
4611
4718
|
message: "cursor-agent found (EXPERIMENTAL: headless mode may need a TTY; auth check is best-effort)"
|
|
4612
4719
|
};
|
|
4613
4720
|
} catch (err) {
|
|
@@ -4704,6 +4811,7 @@ var init_local_model_runner = __esm({
|
|
|
4704
4811
|
"use strict";
|
|
4705
4812
|
init_codex_runner();
|
|
4706
4813
|
init_agent_key_store();
|
|
4814
|
+
init_agent_auth_tier();
|
|
4707
4815
|
LOCAL_API_KEY_ENV = "VO_CODE_RUNNER_LOCAL_API_KEY";
|
|
4708
4816
|
LOCAL_PROVIDERS = ["ollama", "lmstudio"];
|
|
4709
4817
|
DEFAULT_LOCAL_PROVIDER = "ollama";
|
|
@@ -4756,6 +4864,10 @@ var init_local_model_runner = __esm({
|
|
|
4756
4864
|
costBasis() {
|
|
4757
4865
|
return "local_zero";
|
|
4758
4866
|
}
|
|
4867
|
+
/** Dispatch-time billing tier: local inference is never billed by a vendor. */
|
|
4868
|
+
authTier() {
|
|
4869
|
+
return safeAuthTier(() => authTierFromCostBasis(this.costBasis()));
|
|
4870
|
+
}
|
|
4759
4871
|
describeAuth(env2 = process.env) {
|
|
4760
4872
|
const authEnv = this.applyAuthEnv(env2);
|
|
4761
4873
|
const provider = resolveLocalProvider(this.env);
|
|
@@ -4813,6 +4925,7 @@ var init_local_model_runner = __esm({
|
|
|
4813
4925
|
return {
|
|
4814
4926
|
installed: true,
|
|
4815
4927
|
authenticated: true,
|
|
4928
|
+
authTier: this.authTier(),
|
|
4816
4929
|
message: `${provider} reachable; model "${model}" configured (local-only, no cloud spend)`
|
|
4817
4930
|
};
|
|
4818
4931
|
}
|
|
@@ -4901,7 +5014,7 @@ var init_openai_compatible_runner = __esm({
|
|
|
4901
5014
|
buildArgs(opts = {}) {
|
|
4902
5015
|
void opts;
|
|
4903
5016
|
throw new Error(
|
|
4904
|
-
"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."
|
|
4905
5018
|
);
|
|
4906
5019
|
}
|
|
4907
5020
|
/** Codex JSONL events map identically → reuse the proven parser. */
|
|
@@ -4924,14 +5037,14 @@ var init_openai_compatible_runner = __esm({
|
|
|
4924
5037
|
describeAuth(env2 = process.env) {
|
|
4925
5038
|
const hasKey = Boolean(String(env2[OAI_API_KEY_ENV] || "").trim());
|
|
4926
5039
|
const baseUrl = resolveOaiBaseUrl(env2);
|
|
4927
|
-
return `oai-compat endpoint=${baseUrl || "<unset>"} key=${hasKey ? "set" : "MISSING"}`;
|
|
5040
|
+
return `oai-compat RETIRED endpoint=${baseUrl || "<unset>"} key=${hasKey ? "set" : "MISSING"}`;
|
|
4928
5041
|
}
|
|
4929
|
-
/**
|
|
5042
|
+
/** Always unavailable: the lane is retired, so nothing can authenticate it. */
|
|
4930
5043
|
async checkAuth() {
|
|
4931
5044
|
return {
|
|
4932
5045
|
installed: false,
|
|
4933
5046
|
authenticated: false,
|
|
4934
|
-
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"
|
|
4935
5048
|
};
|
|
4936
5049
|
}
|
|
4937
5050
|
};
|
|
@@ -7080,11 +7193,18 @@ async function collectAgentAvailability({
|
|
|
7080
7193
|
new Promise((resolve2) => setTimeout(() => resolve2(null), probeTimeoutMs))
|
|
7081
7194
|
]);
|
|
7082
7195
|
if (!r) return degraded;
|
|
7196
|
+
const installed = Boolean(r?.installed);
|
|
7197
|
+
const authenticated = Boolean(r?.authenticated);
|
|
7198
|
+
const authTier = resolveReportedAuthTier({ authTier: r?.authTier, installed, authenticated });
|
|
7083
7199
|
return {
|
|
7084
7200
|
agent,
|
|
7085
|
-
installed
|
|
7086
|
-
authenticated
|
|
7087
|
-
...typeof r?.version === "string" && r.version ? { version: r.version } : {}
|
|
7201
|
+
installed,
|
|
7202
|
+
authenticated,
|
|
7203
|
+
...typeof r?.version === "string" && r.version ? { version: r.version } : {},
|
|
7204
|
+
// Omitted when unknown, which is what an older daemon's silence already
|
|
7205
|
+
// means — the control-plane schema resolves BOTH to 'unknown'. Never
|
|
7206
|
+
// invent a tier to fill the gap.
|
|
7207
|
+
...authTier !== AUTH_TIER_UNKNOWN ? { auth_tier: authTier } : {}
|
|
7088
7208
|
};
|
|
7089
7209
|
} catch {
|
|
7090
7210
|
return { agent, installed: false, authenticated: false };
|
|
@@ -7147,6 +7267,7 @@ var init_agent_availability = __esm({
|
|
|
7147
7267
|
"use strict";
|
|
7148
7268
|
init_resolve_runner();
|
|
7149
7269
|
init_agent_auth_probe_process();
|
|
7270
|
+
init_agent_auth_tier();
|
|
7150
7271
|
DEFAULT_TTL_MS = 5 * 60 * 1e3;
|
|
7151
7272
|
PROBE_TIMEOUT_MS = 1e4;
|
|
7152
7273
|
}
|
|
@@ -7273,26 +7394,183 @@ var init_local_model_remote_config = __esm({
|
|
|
7273
7394
|
}
|
|
7274
7395
|
});
|
|
7275
7396
|
|
|
7276
|
-
// ../../scripts/virtual-office/code-runner/account-usage.mjs
|
|
7277
|
-
import
|
|
7397
|
+
// ../../scripts/virtual-office/code-runner/account-usage/shared.mjs
|
|
7398
|
+
import crypto from "node:crypto";
|
|
7278
7399
|
import fs6 from "node:fs";
|
|
7400
|
+
function accountKey(agent, rawId) {
|
|
7401
|
+
const id = typeof rawId === "string" ? rawId.trim() : "";
|
|
7402
|
+
if (!id) return null;
|
|
7403
|
+
try {
|
|
7404
|
+
return crypto.scryptSync(`${agent}:${id}`, ACCOUNT_KEY_SALT, 8).toString("hex");
|
|
7405
|
+
} catch {
|
|
7406
|
+
return null;
|
|
7407
|
+
}
|
|
7408
|
+
}
|
|
7409
|
+
function makeUsageRow({
|
|
7410
|
+
agent,
|
|
7411
|
+
sevenDay,
|
|
7412
|
+
fiveHour,
|
|
7413
|
+
monthly,
|
|
7414
|
+
source,
|
|
7415
|
+
capturedAt,
|
|
7416
|
+
accountId,
|
|
7417
|
+
sevenDayResetsAt,
|
|
7418
|
+
fiveHourResetsAt,
|
|
7419
|
+
monthlyResetsAt
|
|
7420
|
+
}) {
|
|
7421
|
+
const seven = clampPct(sevenDay);
|
|
7422
|
+
const five = clampPct(fiveHour);
|
|
7423
|
+
const month = clampPct(monthly);
|
|
7424
|
+
if (seven === null && five === null && month === null) return null;
|
|
7425
|
+
const row = {
|
|
7426
|
+
agent,
|
|
7427
|
+
seven_day_used_pct: seven,
|
|
7428
|
+
five_hour_used_pct: five,
|
|
7429
|
+
source
|
|
7430
|
+
};
|
|
7431
|
+
if (month !== null) row.monthly_used_pct = month;
|
|
7432
|
+
if (typeof monthlyResetsAt === "string" && monthlyResetsAt) {
|
|
7433
|
+
row.monthly_resets_at = monthlyResetsAt;
|
|
7434
|
+
}
|
|
7435
|
+
if (typeof capturedAt === "string" && capturedAt) row.captured_at = capturedAt;
|
|
7436
|
+
const key = accountKey(agent, accountId);
|
|
7437
|
+
if (key) row.account_key = key;
|
|
7438
|
+
if (typeof sevenDayResetsAt === "string" && sevenDayResetsAt) {
|
|
7439
|
+
row.seven_day_resets_at = sevenDayResetsAt;
|
|
7440
|
+
}
|
|
7441
|
+
if (typeof fiveHourResetsAt === "string" && fiveHourResetsAt) {
|
|
7442
|
+
row.five_hour_resets_at = fiveHourResetsAt;
|
|
7443
|
+
}
|
|
7444
|
+
return row;
|
|
7445
|
+
}
|
|
7446
|
+
var clampPct, readJson, ACCOUNT_KEY_SALT;
|
|
7447
|
+
var init_shared = __esm({
|
|
7448
|
+
"../../scripts/virtual-office/code-runner/account-usage/shared.mjs"() {
|
|
7449
|
+
"use strict";
|
|
7450
|
+
clampPct = (v) => {
|
|
7451
|
+
const n = typeof v === "number" ? v : typeof v === "string" && v.trim() !== "" ? Number(v) : NaN;
|
|
7452
|
+
return Number.isFinite(n) ? Math.min(100, Math.max(0, Math.round(n))) : null;
|
|
7453
|
+
};
|
|
7454
|
+
readJson = (p) => {
|
|
7455
|
+
try {
|
|
7456
|
+
return JSON.parse(fs6.readFileSync(p, "utf8"));
|
|
7457
|
+
} catch {
|
|
7458
|
+
return null;
|
|
7459
|
+
}
|
|
7460
|
+
};
|
|
7461
|
+
ACCOUNT_KEY_SALT = "algohq/account-usage/v1";
|
|
7462
|
+
}
|
|
7463
|
+
});
|
|
7464
|
+
|
|
7465
|
+
// ../../scripts/virtual-office/code-runner/account-usage/claude.mjs
|
|
7279
7466
|
import os3 from "node:os";
|
|
7280
7467
|
import path14 from "node:path";
|
|
7281
|
-
function
|
|
7282
|
-
const
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7468
|
+
function usageBaseUrl(env2 = process.env) {
|
|
7469
|
+
const raw = env2.ANTHROPIC_BASE_URL || "https://api.anthropic.com";
|
|
7470
|
+
return String(raw).replace(/\/+$/, "");
|
|
7471
|
+
}
|
|
7472
|
+
function readOAuthToken({ homeDir = os3.homedir(), read = readJson, now = Date.now() } = {}) {
|
|
7473
|
+
const creds = read(path14.join(homeDir, ".claude", ".credentials.json"));
|
|
7474
|
+
const oauth = creds && typeof creds === "object" ? creds.claudeAiOauth : null;
|
|
7475
|
+
if (!oauth || typeof oauth !== "object") return null;
|
|
7476
|
+
const token2 = typeof oauth.accessToken === "string" ? oauth.accessToken.trim() : "";
|
|
7477
|
+
if (!token2) return null;
|
|
7478
|
+
const expiresAt = Number(oauth.expiresAt);
|
|
7479
|
+
if (Number.isFinite(expiresAt) && expiresAt > 0 && expiresAt <= now) return null;
|
|
7480
|
+
return token2;
|
|
7481
|
+
}
|
|
7482
|
+
function readAccountId({ homeDir = os3.homedir(), read = readJson } = {}) {
|
|
7483
|
+
const cfg = read(path14.join(homeDir, ".claude.json"));
|
|
7484
|
+
const account = cfg && typeof cfg === "object" ? cfg.oauthAccount : null;
|
|
7485
|
+
return account && typeof account.accountUuid === "string" ? account.accountUuid : null;
|
|
7486
|
+
}
|
|
7487
|
+
function entryPct(entry) {
|
|
7488
|
+
if (!entry || typeof entry !== "object") return null;
|
|
7489
|
+
for (const field of ["used_percentage", "utilization", "percent"]) {
|
|
7490
|
+
const pct = clampPct(entry[field]);
|
|
7491
|
+
if (pct !== null) return pct;
|
|
7286
7492
|
}
|
|
7287
|
-
|
|
7288
|
-
|
|
7493
|
+
return null;
|
|
7494
|
+
}
|
|
7495
|
+
function entryResetsAt(entry) {
|
|
7496
|
+
if (!entry || typeof entry !== "object") return null;
|
|
7497
|
+
for (const field of ["resets_at", "reset_at", "resetsAt"]) {
|
|
7498
|
+
const value = entry[field];
|
|
7499
|
+
if (typeof value === "string" && value) return value;
|
|
7500
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
7501
|
+
return new Date(value * 1e3).toISOString();
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
return null;
|
|
7289
7505
|
}
|
|
7290
|
-
function
|
|
7506
|
+
function parseOAuthUsage(body) {
|
|
7507
|
+
if (!body || typeof body !== "object") return null;
|
|
7508
|
+
let fiveHour = null;
|
|
7509
|
+
let sevenDay = null;
|
|
7510
|
+
const list = Array.isArray(body) ? body : Array.isArray(body.limits) ? body.limits : null;
|
|
7511
|
+
if (list) {
|
|
7512
|
+
for (const entry of list) {
|
|
7513
|
+
const kind = entry && typeof entry.kind === "string" ? entry.kind : "";
|
|
7514
|
+
if ((kind === "five_hour" || kind === "session") && !fiveHour) fiveHour = entry;
|
|
7515
|
+
else if ((kind === "seven_day" || kind === "weekly_all") && !sevenDay) sevenDay = entry;
|
|
7516
|
+
}
|
|
7517
|
+
}
|
|
7518
|
+
if (!fiveHour && body.five_hour) fiveHour = body.five_hour;
|
|
7519
|
+
if (!sevenDay && body.seven_day) sevenDay = body.seven_day;
|
|
7520
|
+
const five = entryPct(fiveHour);
|
|
7521
|
+
const seven = entryPct(sevenDay);
|
|
7522
|
+
if (five === null && seven === null) return null;
|
|
7523
|
+
return {
|
|
7524
|
+
five_hour_used_pct: five,
|
|
7525
|
+
seven_day_used_pct: seven,
|
|
7526
|
+
five_hour_resets_at: entryResetsAt(fiveHour),
|
|
7527
|
+
seven_day_resets_at: entryResetsAt(sevenDay)
|
|
7528
|
+
};
|
|
7529
|
+
}
|
|
7530
|
+
async function readClaudeOAuthUsage({
|
|
7531
|
+
fetchImpl = fetch,
|
|
7532
|
+
env: env2 = process.env,
|
|
7533
|
+
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
7291
7534
|
homeDir = os3.homedir(),
|
|
7292
|
-
read
|
|
7293
|
-
now = Date.now()
|
|
7294
|
-
mtimeMs = mtimeMsOf
|
|
7535
|
+
read = readJson,
|
|
7536
|
+
now = () => Date.now()
|
|
7295
7537
|
} = {}) {
|
|
7538
|
+
const token2 = readOAuthToken({ homeDir, read, now: now() });
|
|
7539
|
+
if (!token2) return null;
|
|
7540
|
+
const controller = new AbortController();
|
|
7541
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
7542
|
+
try {
|
|
7543
|
+
const res = await fetchImpl(`${usageBaseUrl(env2)}${USAGE_PATH}`, {
|
|
7544
|
+
method: "GET",
|
|
7545
|
+
headers: {
|
|
7546
|
+
authorization: `Bearer ${token2}`,
|
|
7547
|
+
"anthropic-beta": OAUTH_BETA,
|
|
7548
|
+
"content-type": "application/json",
|
|
7549
|
+
accept: "application/json"
|
|
7550
|
+
},
|
|
7551
|
+
signal: controller.signal
|
|
7552
|
+
});
|
|
7553
|
+
if (!res || !res.ok) return null;
|
|
7554
|
+
const parsed = parseOAuthUsage(await res.json());
|
|
7555
|
+
if (!parsed) return null;
|
|
7556
|
+
return makeUsageRow({
|
|
7557
|
+
agent: "claude",
|
|
7558
|
+
source: "oauth",
|
|
7559
|
+
// The response describes the account AS OF NOW, so the reading time is now.
|
|
7560
|
+
capturedAt: new Date(now()).toISOString(),
|
|
7561
|
+
accountId: readAccountId({ homeDir, read }),
|
|
7562
|
+
sevenDay: parsed.seven_day_used_pct,
|
|
7563
|
+
fiveHour: parsed.five_hour_used_pct,
|
|
7564
|
+
sevenDayResetsAt: parsed.seven_day_resets_at,
|
|
7565
|
+
fiveHourResetsAt: parsed.five_hour_resets_at
|
|
7566
|
+
});
|
|
7567
|
+
} catch {
|
|
7568
|
+
return null;
|
|
7569
|
+
} finally {
|
|
7570
|
+
clearTimeout(timer);
|
|
7571
|
+
}
|
|
7572
|
+
}
|
|
7573
|
+
function readClaudeFileUsage({ homeDir = os3.homedir(), read: rawRead = readJson } = {}) {
|
|
7296
7574
|
const read = (p) => {
|
|
7297
7575
|
try {
|
|
7298
7576
|
return rawRead(p);
|
|
@@ -7300,55 +7578,89 @@ function readClaudeUsage({
|
|
|
7300
7578
|
return null;
|
|
7301
7579
|
}
|
|
7302
7580
|
};
|
|
7303
|
-
const
|
|
7304
|
-
const status = read(
|
|
7305
|
-
if (status && (status.seven_day || status.five_hour)
|
|
7306
|
-
const
|
|
7581
|
+
const accountId = readAccountId({ homeDir, read });
|
|
7582
|
+
const status = read(path14.join(homeDir, ".claude", "claude-usage.json"));
|
|
7583
|
+
if (status && (status.seven_day || status.five_hour)) {
|
|
7584
|
+
const row = makeUsageRow({
|
|
7307
7585
|
agent: "claude",
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7586
|
+
source: "statusline",
|
|
7587
|
+
capturedAt: typeof status.capturedAt === "string" ? status.capturedAt : null,
|
|
7588
|
+
accountId,
|
|
7589
|
+
sevenDay: status.seven_day?.used_percentage,
|
|
7590
|
+
fiveHour: status.five_hour?.used_percentage,
|
|
7591
|
+
sevenDayResetsAt: status.seven_day?.resets_at ?? null,
|
|
7592
|
+
fiveHourResetsAt: status.five_hour?.resets_at ?? null
|
|
7593
|
+
});
|
|
7594
|
+
if (row) return row;
|
|
7312
7595
|
}
|
|
7313
|
-
const
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
const entry = {
|
|
7596
|
+
const weekly = read(path14.join(homeDir, ".claude", "claude-weekly-usage.json"));
|
|
7597
|
+
if (weekly) {
|
|
7598
|
+
const row = makeUsageRow({
|
|
7317
7599
|
agent: "claude",
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7600
|
+
source: "file",
|
|
7601
|
+
capturedAt: typeof weekly.capturedAt === "string" ? weekly.capturedAt : null,
|
|
7602
|
+
accountId,
|
|
7603
|
+
sevenDay: weekly.sevenDayPct,
|
|
7604
|
+
fiveHour: weekly.fiveHourPct,
|
|
7605
|
+
sevenDayResetsAt: weekly.sevenDayResetsAt ?? null
|
|
7606
|
+
});
|
|
7607
|
+
if (row) return row;
|
|
7322
7608
|
}
|
|
7323
7609
|
return null;
|
|
7324
7610
|
}
|
|
7325
|
-
function
|
|
7326
|
-
|
|
7327
|
-
|
|
7611
|
+
async function readClaudeUsage(opts = {}) {
|
|
7612
|
+
try {
|
|
7613
|
+
const live = await readClaudeOAuthUsage(opts);
|
|
7614
|
+
if (live) return live;
|
|
7615
|
+
} catch {
|
|
7616
|
+
}
|
|
7617
|
+
return readClaudeFileUsage(opts);
|
|
7328
7618
|
}
|
|
7619
|
+
var USAGE_PATH, OAUTH_BETA, DEFAULT_TIMEOUT_MS;
|
|
7620
|
+
var init_claude = __esm({
|
|
7621
|
+
"../../scripts/virtual-office/code-runner/account-usage/claude.mjs"() {
|
|
7622
|
+
"use strict";
|
|
7623
|
+
init_shared();
|
|
7624
|
+
USAGE_PATH = "/api/oauth/usage";
|
|
7625
|
+
OAUTH_BETA = "oauth-2025-04-20";
|
|
7626
|
+
DEFAULT_TIMEOUT_MS = 5e3;
|
|
7627
|
+
}
|
|
7628
|
+
});
|
|
7629
|
+
|
|
7630
|
+
// ../../scripts/virtual-office/code-runner/account-usage/codex.mjs
|
|
7631
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
7329
7632
|
function weeklyWindow(snapshot2) {
|
|
7330
7633
|
if (!snapshot2 || typeof snapshot2 !== "object") return null;
|
|
7331
7634
|
const windows = [snapshot2.primary, snapshot2.secondary].filter(Boolean);
|
|
7332
7635
|
return windows.find((window) => Number(window?.windowDurationMins) === 7 * 24 * 60) ?? windows.find((window) => Number(window?.windowDurationMins) >= 6 * 24 * 60) ?? null;
|
|
7333
7636
|
}
|
|
7334
|
-
function
|
|
7637
|
+
function resetsAtIso(window) {
|
|
7638
|
+
const raw = Number(window?.resetsAt);
|
|
7639
|
+
if (!Number.isFinite(raw) || raw <= 0) return null;
|
|
7640
|
+
return new Date(raw * 1e3).toISOString();
|
|
7641
|
+
}
|
|
7642
|
+
function parseCodexUsage(response, { now = () => Date.now() } = {}) {
|
|
7335
7643
|
const result = response?.result;
|
|
7336
7644
|
const snapshot2 = result?.rateLimitsByLimitId?.codex ?? result?.rateLimits;
|
|
7337
7645
|
const weekly = weeklyWindow(snapshot2);
|
|
7338
7646
|
const used = clampPct(weekly?.usedPercent);
|
|
7339
7647
|
if (used === null) return null;
|
|
7340
|
-
return {
|
|
7648
|
+
return makeUsageRow({
|
|
7341
7649
|
agent: "codex",
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7650
|
+
source: "app-server",
|
|
7651
|
+
capturedAt: new Date(now()).toISOString(),
|
|
7652
|
+
sevenDay: used,
|
|
7653
|
+
fiveHour: null,
|
|
7654
|
+
sevenDayResetsAt: resetsAtIso(weekly)
|
|
7655
|
+
});
|
|
7345
7656
|
}
|
|
7346
7657
|
function readCodexUsage({
|
|
7347
7658
|
spawnImpl = spawn4,
|
|
7348
7659
|
resolveBinary = resolveCodexBinary,
|
|
7349
7660
|
timeoutMs = 8e3,
|
|
7350
7661
|
env: env2 = process.env,
|
|
7351
|
-
platform = process.platform
|
|
7662
|
+
platform = process.platform,
|
|
7663
|
+
now = () => Date.now()
|
|
7352
7664
|
} = {}) {
|
|
7353
7665
|
return new Promise((resolve2) => {
|
|
7354
7666
|
let child;
|
|
@@ -7370,7 +7682,8 @@ function readCodexUsage({
|
|
|
7370
7682
|
child = spawnImpl(binary, ["app-server", "--stdio"], {
|
|
7371
7683
|
env: env2,
|
|
7372
7684
|
windowsHide: true,
|
|
7373
|
-
shell:
|
|
7685
|
+
shell: false,
|
|
7686
|
+
windowsVerbatimArguments: false,
|
|
7374
7687
|
stdio: ["pipe", "pipe", "ignore"]
|
|
7375
7688
|
});
|
|
7376
7689
|
child.on("error", () => finish(null));
|
|
@@ -7394,7 +7707,7 @@ function readCodexUsage({
|
|
|
7394
7707
|
child.stdin?.write(`${JSON.stringify({ method: "account/rateLimits/read", id: 2 })}
|
|
7395
7708
|
`);
|
|
7396
7709
|
} else if (message?.id === 2) {
|
|
7397
|
-
finish(parseCodexUsage(message));
|
|
7710
|
+
finish(parseCodexUsage(message, { now }));
|
|
7398
7711
|
}
|
|
7399
7712
|
}
|
|
7400
7713
|
});
|
|
@@ -7412,14 +7725,29 @@ function readCodexUsage({
|
|
|
7412
7725
|
}
|
|
7413
7726
|
});
|
|
7414
7727
|
}
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
} catch {
|
|
7728
|
+
var init_codex = __esm({
|
|
7729
|
+
"../../scripts/virtual-office/code-runner/account-usage/codex.mjs"() {
|
|
7730
|
+
"use strict";
|
|
7731
|
+
init_shared();
|
|
7732
|
+
init_codex_runner();
|
|
7421
7733
|
}
|
|
7422
|
-
|
|
7734
|
+
});
|
|
7735
|
+
|
|
7736
|
+
// ../../scripts/virtual-office/code-runner/account-usage/index.mjs
|
|
7737
|
+
function collectAccountUsage(opts = {}) {
|
|
7738
|
+
const claude = readClaudeFileUsage(opts);
|
|
7739
|
+
return claude ? [claude] : [];
|
|
7740
|
+
}
|
|
7741
|
+
async function collectConnectedAccountUsage({
|
|
7742
|
+
readClaude = readClaudeUsage,
|
|
7743
|
+
readCodex = readCodexUsage,
|
|
7744
|
+
...agentOptions
|
|
7745
|
+
} = {}) {
|
|
7746
|
+
const settled = await Promise.allSettled([
|
|
7747
|
+
readClaude(agentOptions),
|
|
7748
|
+
readCodex(agentOptions)
|
|
7749
|
+
]);
|
|
7750
|
+
return settled.map((outcome) => outcome.status === "fulfilled" ? outcome.value : null).filter(Boolean);
|
|
7423
7751
|
}
|
|
7424
7752
|
function makeAccountUsageProvider({
|
|
7425
7753
|
ttlMs = DEFAULT_TTL_MS2,
|
|
@@ -7447,35 +7775,31 @@ function makeAccountUsageProvider({
|
|
|
7447
7775
|
}
|
|
7448
7776
|
};
|
|
7449
7777
|
}
|
|
7450
|
-
var
|
|
7778
|
+
var AGENT_USAGE_CAPABILITY, DEFAULT_TTL_MS2;
|
|
7451
7779
|
var init_account_usage = __esm({
|
|
7452
|
-
"../../scripts/virtual-office/code-runner/account-usage.mjs"() {
|
|
7780
|
+
"../../scripts/virtual-office/code-runner/account-usage/index.mjs"() {
|
|
7453
7781
|
"use strict";
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
return null;
|
|
7464
|
-
}
|
|
7465
|
-
};
|
|
7466
|
-
STALE_AFTER_MS = 2 * 60 * 60 * 1e3;
|
|
7467
|
-
mtimeMsOf = (p) => {
|
|
7468
|
-
try {
|
|
7469
|
-
return fs6.statSync(p).mtimeMs;
|
|
7470
|
-
} catch {
|
|
7471
|
-
return null;
|
|
7472
|
-
}
|
|
7473
|
-
};
|
|
7474
|
-
isFresh = (ageMs) => ageMs !== null && ageMs <= STALE_AFTER_MS;
|
|
7782
|
+
init_claude();
|
|
7783
|
+
init_codex();
|
|
7784
|
+
init_shared();
|
|
7785
|
+
AGENT_USAGE_CAPABILITY = Object.freeze({
|
|
7786
|
+
claude: Object.freeze({ five_hour: true, seven_day: true, monthly: false }),
|
|
7787
|
+
codex: Object.freeze({ five_hour: false, seven_day: true, monthly: false }),
|
|
7788
|
+
cursor: Object.freeze({ five_hour: false, seven_day: false, monthly: false }),
|
|
7789
|
+
gemini: Object.freeze({ five_hour: false, seven_day: false, monthly: false })
|
|
7790
|
+
});
|
|
7475
7791
|
DEFAULT_TTL_MS2 = 5 * 60 * 1e3;
|
|
7476
7792
|
}
|
|
7477
7793
|
});
|
|
7478
7794
|
|
|
7795
|
+
// ../../scripts/virtual-office/code-runner/account-usage.mjs
|
|
7796
|
+
var init_account_usage2 = __esm({
|
|
7797
|
+
"../../scripts/virtual-office/code-runner/account-usage.mjs"() {
|
|
7798
|
+
"use strict";
|
|
7799
|
+
init_account_usage();
|
|
7800
|
+
}
|
|
7801
|
+
});
|
|
7802
|
+
|
|
7479
7803
|
// ../../scripts/virtual-office/code-runner/ci-repair-evidence.mjs
|
|
7480
7804
|
function extractWorkflowRunIds(links = []) {
|
|
7481
7805
|
const ids = [];
|
|
@@ -8268,7 +8592,6 @@ function makeWatchRunner({
|
|
|
8268
8592
|
repairAttempt: chain.attempt + 1
|
|
8269
8593
|
}),
|
|
8270
8594
|
...operatorId && operatorId !== "admin" ? { on_behalf_of_operator_id: operatorId } : {},
|
|
8271
|
-
agent: "claude",
|
|
8272
8595
|
dispatch_mode: "fast",
|
|
8273
8596
|
max_turns: 80,
|
|
8274
8597
|
max_budget_usd: chain.per_attempt_budget_usd,
|
|
@@ -10180,7 +10503,15 @@ var init_agent_process_env = __esm({
|
|
|
10180
10503
|
"WINDIR",
|
|
10181
10504
|
"VO_RUNNER_PREFER_LOGIN",
|
|
10182
10505
|
"VO_RUNNER_CLAUDE_PREFER_LOGIN",
|
|
10183
|
-
"VO_RUNNER_CODEX_PREFER_LOGIN"
|
|
10506
|
+
"VO_RUNNER_CODEX_PREFER_LOGIN",
|
|
10507
|
+
// The tier-1 opt-out (PR #9242). Auth-preference flags are only visible to a
|
|
10508
|
+
// runner's applyAuthEnv() if they are listed HERE: the daemon builds the child
|
|
10509
|
+
// env with buildAgentProcessEnv(process.env) (code-runner-daemon.mjs:117), so
|
|
10510
|
+
// anything absent from this set is stripped before withAnthropicKey ever sees
|
|
10511
|
+
// it. #9242 added VO_RUNNER_PREFER_KEY without this line, which left the
|
|
10512
|
+
// escape hatch inert — an operator who set it still got the subscription.
|
|
10513
|
+
"VO_RUNNER_PREFER_KEY",
|
|
10514
|
+
"VO_RUNNER_CLAUDE_PREFER_KEY"
|
|
10184
10515
|
]);
|
|
10185
10516
|
}
|
|
10186
10517
|
});
|
|
@@ -12444,7 +12775,7 @@ var init_code_runner_daemon = __esm({
|
|
|
12444
12775
|
init_runner_capacity();
|
|
12445
12776
|
init_agent_availability();
|
|
12446
12777
|
init_local_model_remote_config();
|
|
12447
|
-
|
|
12778
|
+
init_account_usage2();
|
|
12448
12779
|
init_pr_watcher();
|
|
12449
12780
|
init_existing_pr_target();
|
|
12450
12781
|
init_watch_cycle_coordinator();
|