@algosuite/vo-mcp 0.2.0-beta.26 → 0.2.0-beta.27

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.
@@ -3026,23 +3026,40 @@ 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 withAnthropicKey(baseEnv = {}, { getKey = getAnthropicKey } = {}) {
3030
- if (isTruthyFlag(baseEnv[CLAUDE_PREFER_LOGIN_ENV]) || isTruthyFlag(baseEnv[PREFER_LOGIN_ENV])) {
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
+ if (wantsLogin(baseEnv)) {
3031
3037
  const next = { ...baseEnv };
3032
3038
  delete next.ANTHROPIC_API_KEY;
3033
3039
  return next;
3034
3040
  }
3035
3041
  if (baseEnv.ANTHROPIC_API_KEY) return { ...baseEnv };
3036
3042
  const key = getKey();
3037
- return key ? { ...baseEnv, ANTHROPIC_API_KEY: key } : { ...baseEnv };
3043
+ if (!key) return { ...baseEnv };
3044
+ if (!wantsKey(baseEnv) && probeLogin() === true) return { ...baseEnv };
3045
+ return { ...baseEnv, ANTHROPIC_API_KEY: key };
3046
+ }
3047
+ function claudeCostBasis(env2 = process.env) {
3048
+ return String(env2.ANTHROPIC_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
3038
3049
  }
3039
- function describeAnthropicAuthSource(baseEnv = {}, { getKey = getAnthropicKey } = {}) {
3040
- if (isTruthyFlag(baseEnv[CLAUDE_PREFER_LOGIN_ENV]) || isTruthyFlag(baseEnv[PREFER_LOGIN_ENV])) {
3050
+ function describeAnthropicAuthSource(baseEnv = {}, { getKey = getAnthropicKey, probeLogin = probeClaudeLoginState } = {}) {
3051
+ if (wantsLogin(baseEnv)) {
3041
3052
  return "claude auth login (VO_RUNNER_PREFER_LOGIN set \u2014 any API key ignored)";
3042
3053
  }
3043
3054
  if (baseEnv.ANTHROPIC_API_KEY) return "ANTHROPIC_API_KEY from environment";
3044
- if (getKey()) return "ANTHROPIC_API_KEY from OS keychain";
3045
- return "claude auth login session (no API key set)";
3055
+ if (!getKey()) return "claude auth login session (no API key set)";
3056
+ if (wantsKey(baseEnv)) {
3057
+ return "ANTHROPIC_API_KEY from OS keychain (VO_RUNNER_PREFER_KEY set \u2014 subscription ignored)";
3058
+ }
3059
+ if (probeLogin() === true) {
3060
+ return "claude auth login session (subscription beats the stored keychain key)";
3061
+ }
3062
+ return "ANTHROPIC_API_KEY from OS keychain";
3046
3063
  }
3047
3064
  function augmentAuthError(summary) {
3048
3065
  const s = String(summary ?? "");
@@ -3051,20 +3068,20 @@ function augmentAuthError(summary) {
3051
3068
  \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"\`.`;
3052
3069
  }
3053
3070
  function probeClaudeLoginState({
3054
- spawn: spawn5 = spawnSync2,
3071
+ spawn: spawn6 = spawnSync2,
3055
3072
  buildWindowsLaunch = buildWindowsClaudeLaunch,
3056
3073
  platform = process.platform
3057
3074
  } = {}) {
3058
3075
  try {
3059
3076
  const launch = platform === "win32" ? buildWindowsLaunch({ bin: "claude", args: ["auth", "status"] }) : { bin: "claude", args: ["auth", "status"], spawnOptions: { windowsHide: true } };
3060
- const st = spawn5(launch.bin, launch.args, { ...launch.spawnOptions, timeout: 5e3, encoding: "utf8" });
3077
+ const st = spawn6(launch.bin, launch.args, { ...launch.spawnOptions, timeout: 5e3, encoding: "utf8" });
3061
3078
  const parsed = JSON.parse(String(st.stdout || "").trim() || "{}");
3062
3079
  return typeof parsed.loggedIn === "boolean" ? parsed.loggedIn : null;
3063
3080
  } catch {
3064
3081
  return null;
3065
3082
  }
3066
3083
  }
3067
- var require2, KEY_SERVICE, KEY_ACCOUNT, _entryCtor, _loadTried, PREFER_LOGIN_ENV, CLAUDE_PREFER_LOGIN_ENV, AUTH_ERROR_RE;
3084
+ 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
3085
  var init_anthropic_key_store = __esm({
3069
3086
  "../../scripts/virtual-office/code-runner/anthropic-key-store.mjs"() {
3070
3087
  "use strict";
@@ -3075,6 +3092,8 @@ var init_anthropic_key_store = __esm({
3075
3092
  _loadTried = false;
3076
3093
  PREFER_LOGIN_ENV = "VO_RUNNER_PREFER_LOGIN";
3077
3094
  CLAUDE_PREFER_LOGIN_ENV = "VO_RUNNER_CLAUDE_PREFER_LOGIN";
3095
+ PREFER_KEY_ENV = "VO_RUNNER_PREFER_KEY";
3096
+ CLAUDE_PREFER_KEY_ENV = "VO_RUNNER_CLAUDE_PREFER_KEY";
3078
3097
  AUTH_ERROR_RE = /\b401\b|invalid[^.]{0,24}(authentication|credential)|authentication_error|unauthorized|not[ _-]?authenticated/i;
3079
3098
  }
3080
3099
  });
@@ -3308,11 +3327,11 @@ import { spawnSync as spawnSync4 } from "node:child_process";
3308
3327
  function terminateAgentProcessTree({
3309
3328
  child,
3310
3329
  platform = process.platform,
3311
- spawn: spawn5 = spawnSync4
3330
+ spawn: spawn6 = spawnSync4
3312
3331
  } = {}) {
3313
3332
  if (!child || !Number.isInteger(child.pid) || child.pid <= 0) return false;
3314
3333
  if (platform === "win32") {
3315
- const result = spawn5("taskkill", ["/PID", String(child.pid), "/T", "/F"], {
3334
+ const result = spawn6("taskkill", ["/PID", String(child.pid), "/T", "/F"], {
3316
3335
  windowsHide: true,
3317
3336
  stdio: "ignore",
3318
3337
  timeout: 15e3
@@ -3488,11 +3507,11 @@ function windowsSystemRoot(env2 = process.env) {
3488
3507
  function windowsPowershellExe(env2 = process.env) {
3489
3508
  return path11.join(windowsSystemRoot(env2), "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
3490
3509
  }
3491
- function listProcessCreationTimes({ platform = process.platform, spawn: spawn5 = spawnSync5, env: env2 = process.env, warn = console.warn } = {}) {
3510
+ function listProcessCreationTimes({ platform = process.platform, spawn: spawn6 = spawnSync5, env: env2 = process.env, warn = console.warn } = {}) {
3492
3511
  const map = /* @__PURE__ */ new Map();
3493
3512
  if (platform === "win32") {
3494
3513
  const ps = "Get-CimInstance Win32_Process | ForEach-Object { '{0} {1}' -f $_.ProcessId, (([DateTimeOffset]$_.CreationDate.ToUniversalTime()).ToUnixTimeMilliseconds()) }";
3495
- const result2 = spawn5(windowsPowershellExe(env2), ["-NoProfile", "-NonInteractive", "-Command", ps], {
3514
+ const result2 = spawn6(windowsPowershellExe(env2), ["-NoProfile", "-NonInteractive", "-Command", ps], {
3496
3515
  windowsHide: true,
3497
3516
  encoding: "utf8",
3498
3517
  timeout: 2e4,
@@ -3508,7 +3527,7 @@ function listProcessCreationTimes({ platform = process.platform, spawn: spawn5 =
3508
3527
  }
3509
3528
  return map;
3510
3529
  }
3511
- const result = spawn5("ps", ["-eo", "pid=,lstart="], { encoding: "utf8", timeout: 2e4, maxBuffer: 32 * 1024 * 1024 });
3530
+ const result = spawn6("ps", ["-eo", "pid=,lstart="], { encoding: "utf8", timeout: 2e4, maxBuffer: 32 * 1024 * 1024 });
3512
3531
  if (result.error || result.status !== 0 || typeof result.stdout !== "string") {
3513
3532
  warn(`[orphan-reaper] process enumeration failed (${result.error ? result.error.message : `ps exit ${result.status}`}); reaping nothing this cycle`);
3514
3533
  return map;
@@ -3528,11 +3547,11 @@ function parsePosixPsLine(line) {
3528
3547
  if (!Number.isInteger(pid) || pid <= 0 || !Number.isFinite(when)) return null;
3529
3548
  return { pid, creationMs: when };
3530
3549
  }
3531
- function killProcessTree(pid, { platform = process.platform, spawn: spawn5 = spawnSync5, env: env2 = process.env } = {}) {
3550
+ function killProcessTree(pid, { platform = process.platform, spawn: spawn6 = spawnSync5, env: env2 = process.env } = {}) {
3532
3551
  if (!Number.isInteger(pid) || pid <= 0) return false;
3533
3552
  if (platform === "win32") {
3534
3553
  const taskkill = path11.join(windowsSystemRoot(env2), "System32", "taskkill.exe");
3535
- const r = spawn5(taskkill, ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore", timeout: 15e3 });
3554
+ const r = spawn6(taskkill, ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore", timeout: 15e3 });
3536
3555
  return !r.error && r.status === 0;
3537
3556
  }
3538
3557
  try {
@@ -3734,6 +3753,46 @@ var init_claude_stream_event = __esm({
3734
3753
  }
3735
3754
  });
3736
3755
 
3756
+ // ../../scripts/virtual-office/code-runner/agent-auth-tier.mjs
3757
+ function authTierFromCostBasis(costBasis) {
3758
+ return COST_BASIS_TO_TIER[String(costBasis ?? "")] ?? AUTH_TIER_UNKNOWN;
3759
+ }
3760
+ function safeAuthTier(compute) {
3761
+ try {
3762
+ return normalizeAuthTier(compute());
3763
+ } catch {
3764
+ return AUTH_TIER_UNKNOWN;
3765
+ }
3766
+ }
3767
+ function normalizeAuthTier(value) {
3768
+ return AUTH_TIERS.includes(value) ? value : AUTH_TIER_UNKNOWN;
3769
+ }
3770
+ function resolveReportedAuthTier({ authTier, installed, authenticated } = {}) {
3771
+ if (installed !== true || authenticated !== true) return AUTH_TIER_UNKNOWN;
3772
+ return normalizeAuthTier(authTier);
3773
+ }
3774
+ var AUTH_TIER_SUBSCRIPTION, AUTH_TIER_API_KEY, AUTH_TIER_LOCAL, AUTH_TIER_UNKNOWN, AUTH_TIERS, COST_BASIS_TO_TIER;
3775
+ var init_agent_auth_tier = __esm({
3776
+ "../../scripts/virtual-office/code-runner/agent-auth-tier.mjs"() {
3777
+ "use strict";
3778
+ AUTH_TIER_SUBSCRIPTION = "subscription";
3779
+ AUTH_TIER_API_KEY = "api_key";
3780
+ AUTH_TIER_LOCAL = "local";
3781
+ AUTH_TIER_UNKNOWN = "unknown";
3782
+ AUTH_TIERS = Object.freeze([
3783
+ AUTH_TIER_SUBSCRIPTION,
3784
+ AUTH_TIER_API_KEY,
3785
+ AUTH_TIER_LOCAL,
3786
+ AUTH_TIER_UNKNOWN
3787
+ ]);
3788
+ COST_BASIS_TO_TIER = Object.freeze({
3789
+ subscription_api_equivalent: AUTH_TIER_SUBSCRIPTION,
3790
+ vendor_billed: AUTH_TIER_API_KEY,
3791
+ local_zero: AUTH_TIER_LOCAL
3792
+ });
3793
+ }
3794
+ });
3795
+
3737
3796
  // ../../scripts/virtual-office/code-runner/cli-version-floor.mjs
3738
3797
  function parseCliVersion(output) {
3739
3798
  const match = /\b(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?\b/.exec(String(output ?? ""));
@@ -3803,9 +3862,22 @@ function isTimeout(probe) {
3803
3862
  function notFound(probe) {
3804
3863
  return errorCode(probe?.error) === "ENOENT";
3805
3864
  }
3865
+ function resolveClaudeAuthTier({
3866
+ env: env2 = process.env,
3867
+ loggedIn = null,
3868
+ getStoredKey = getAnthropicKey
3869
+ } = {}) {
3870
+ return safeAuthTier(() => {
3871
+ const spawnEnv = withAnthropicKey(env2, { getKey: getStoredKey, probeLogin: () => loggedIn });
3872
+ const tier = authTierFromCostBasis(claudeCostBasis(spawnEnv));
3873
+ if (tier === AUTH_TIER_SUBSCRIPTION && loggedIn !== true) return AUTH_TIER_UNKNOWN;
3874
+ return tier;
3875
+ });
3876
+ }
3806
3877
  async function checkClaudeAuth({
3807
3878
  spawnVersion = spawnClaudeSync,
3808
3879
  probeLogin = probeClaudeLoginState,
3880
+ getStoredKey = getAnthropicKey,
3809
3881
  env: env2 = process.env
3810
3882
  } = {}) {
3811
3883
  try {
@@ -3855,6 +3927,10 @@ async function checkClaudeAuth({
3855
3927
  return {
3856
3928
  installed: true,
3857
3929
  authenticated: true,
3930
+ // Dispatch-time billing signal, carried on the same probe that already
3931
+ // paid for the login read. Never sent for a non-authenticated result:
3932
+ // there is no tier without a working credential.
3933
+ authTier: resolveClaudeAuthTier({ env: env2, loggedIn, getStoredKey }),
3858
3934
  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
3935
  };
3860
3936
  } catch (error) {
@@ -3870,6 +3946,7 @@ var init_claude_auth_check = __esm({
3870
3946
  "../../scripts/virtual-office/code-runner/claude-auth-check.mjs"() {
3871
3947
  "use strict";
3872
3948
  init_anthropic_key_store();
3949
+ init_agent_auth_tier();
3873
3950
  init_cli_version_floor();
3874
3951
  init_windows_claude_launch();
3875
3952
  FIRST_VERSION_TIMEOUT_MS = 4500;
@@ -4134,7 +4211,7 @@ var init_claude_runner = __esm({
4134
4211
  return withAnthropicKey(env2);
4135
4212
  }
4136
4213
  costBasis(env2 = process.env) {
4137
- return String(env2.ANTHROPIC_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
4214
+ return claudeCostBasis(env2);
4138
4215
  }
4139
4216
  /** Describe which Anthropic auth source the spawn will use (for runner logs). */
4140
4217
  describeAuth(env2 = process.env) {
@@ -4369,12 +4446,13 @@ var init_codex_runner = __esm({
4369
4446
  "../../scripts/virtual-office/code-runner/codex-runner.mjs"() {
4370
4447
  "use strict";
4371
4448
  init_agent_key_store();
4449
+ init_agent_auth_tier();
4372
4450
  init_flat_token_usage();
4373
4451
  CODEX_PREFER_LOGIN_ENV = "VO_RUNNER_CODEX_PREFER_LOGIN";
4374
4452
  LEGACY_PREFER_LOGIN_ENV = "VO_RUNNER_PREFER_LOGIN";
4375
4453
  CodexRunner = class {
4376
- constructor({ spawn: spawn5 = spawnSync6, resolveBinary = resolveCodexBinary, env: env2 = process.env } = {}) {
4377
- this.spawn = spawn5;
4454
+ constructor({ spawn: spawn6 = spawnSync6, resolveBinary = resolveCodexBinary, env: env2 = process.env } = {}) {
4455
+ this.spawn = spawn6;
4378
4456
  this.resolveBinary = resolveBinary;
4379
4457
  this.env = env2;
4380
4458
  }
@@ -4426,6 +4504,19 @@ var init_codex_runner = __esm({
4426
4504
  costBasis(env2 = process.env) {
4427
4505
  return String(env2.OPENAI_API_KEY || env2.CODEX_API_KEY || "").trim() ? "vendor_billed" : "subscription_api_equivalent";
4428
4506
  }
4507
+ /**
4508
+ * Dispatch-time billing tier for the NEXT codex spawn, from the SAME facts
4509
+ * checkAuth() already gathered — no extra subprocess. applyAuthEnv() is a
4510
+ * keychain read in this process (@napi-rs/keyring), not a spawn.
4511
+ *
4512
+ * Codex is the agent where this signal was already computed and then thrown
4513
+ * away: checkAuth() distinguished "API key available (no persisted ChatGPT
4514
+ * login)" from a real login, but only inside a `message` string that the
4515
+ * heartbeat schema strips before storage. This gives that fact a typed home.
4516
+ */
4517
+ authTier(env2 = this.env) {
4518
+ return safeAuthTier(() => authTierFromCostBasis(this.costBasis(this.applyAuthEnv(env2))));
4519
+ }
4429
4520
  /** Best-effort binary + persisted-login probe. Never throws or spends tokens. */
4430
4521
  async checkAuth() {
4431
4522
  try {
@@ -4459,6 +4550,7 @@ ${login.stderr || ""}`.trim();
4459
4550
  installed: true,
4460
4551
  authenticated: true,
4461
4552
  ...versionField,
4553
+ authTier: this.authTier(),
4462
4554
  message: "codex API key available (no persisted ChatGPT login)"
4463
4555
  };
4464
4556
  }
@@ -4473,6 +4565,7 @@ ${login.stderr || ""}`.trim();
4473
4565
  installed: true,
4474
4566
  authenticated: true,
4475
4567
  ...versionField,
4568
+ authTier: this.authTier(),
4476
4569
  message: output || "codex login status succeeded"
4477
4570
  };
4478
4571
  } catch (err) {
@@ -4539,6 +4632,7 @@ var init_cursor_runner = __esm({
4539
4632
  "../../scripts/virtual-office/code-runner/cursor-runner.mjs"() {
4540
4633
  "use strict";
4541
4634
  init_agent_key_store();
4635
+ init_agent_auth_tier();
4542
4636
  init_flat_token_usage();
4543
4637
  CursorRunner = class {
4544
4638
  get binary() {
@@ -4583,6 +4677,16 @@ var init_cursor_runner = __esm({
4583
4677
  costBasis(env2 = process.env) {
4584
4678
  return env2.CURSOR_API_KEY ? "vendor_billed" : "unknown";
4585
4679
  }
4680
+ /**
4681
+ * Dispatch-time billing tier. Inherits costBasis()'s deliberate refusal to
4682
+ * guess: a prior interactive `cursor-agent login` has undocumented
4683
+ * subscription semantics, so it reports 'unknown' rather than claiming a
4684
+ * flat-cost seat the runner cannot actually prove. Keychain read only — the
4685
+ * heartbeat never pays for a subprocess to answer this.
4686
+ */
4687
+ authTier(env2 = process.env) {
4688
+ return safeAuthTier(() => authTierFromCostBasis(this.costBasis(this.applyAuthEnv(env2))));
4689
+ }
4586
4690
  /** Best-effort: is `cursor-agent` on PATH? Never throws. */
4587
4691
  async checkAuth() {
4588
4692
  try {
@@ -4608,6 +4712,7 @@ var init_cursor_runner = __esm({
4608
4712
  return {
4609
4713
  installed: true,
4610
4714
  authenticated: true,
4715
+ authTier: this.authTier(),
4611
4716
  message: "cursor-agent found (EXPERIMENTAL: headless mode may need a TTY; auth check is best-effort)"
4612
4717
  };
4613
4718
  } catch (err) {
@@ -4704,6 +4809,7 @@ var init_local_model_runner = __esm({
4704
4809
  "use strict";
4705
4810
  init_codex_runner();
4706
4811
  init_agent_key_store();
4812
+ init_agent_auth_tier();
4707
4813
  LOCAL_API_KEY_ENV = "VO_CODE_RUNNER_LOCAL_API_KEY";
4708
4814
  LOCAL_PROVIDERS = ["ollama", "lmstudio"];
4709
4815
  DEFAULT_LOCAL_PROVIDER = "ollama";
@@ -4715,12 +4821,12 @@ var init_local_model_runner = __esm({
4715
4821
  LOCAL_MODEL_RE = new RegExp("^[A-Za-z0-9][A-Za-z0-9._/:-]{0,127}$");
4716
4822
  LocalModelRunner = class {
4717
4823
  constructor({
4718
- spawn: spawn5 = null,
4824
+ spawn: spawn6 = null,
4719
4825
  resolveBinary = resolveCodexBinary,
4720
4826
  env: env2 = process.env,
4721
4827
  fetchImpl = globalThis.fetch
4722
4828
  } = {}) {
4723
- this.spawn = spawn5;
4829
+ this.spawn = spawn6;
4724
4830
  this.resolveBinary = resolveBinary;
4725
4831
  this.env = env2;
4726
4832
  this.fetchImpl = fetchImpl;
@@ -4756,6 +4862,10 @@ var init_local_model_runner = __esm({
4756
4862
  costBasis() {
4757
4863
  return "local_zero";
4758
4864
  }
4865
+ /** Dispatch-time billing tier: local inference is never billed by a vendor. */
4866
+ authTier() {
4867
+ return safeAuthTier(() => authTierFromCostBasis(this.costBasis()));
4868
+ }
4759
4869
  describeAuth(env2 = process.env) {
4760
4870
  const authEnv = this.applyAuthEnv(env2);
4761
4871
  const provider = resolveLocalProvider(this.env);
@@ -4813,6 +4923,7 @@ var init_local_model_runner = __esm({
4813
4923
  return {
4814
4924
  installed: true,
4815
4925
  authenticated: true,
4926
+ authTier: this.authTier(),
4816
4927
  message: `${provider} reachable; model "${model}" configured (local-only, no cloud spend)`
4817
4928
  };
4818
4929
  }
@@ -7080,11 +7191,18 @@ async function collectAgentAvailability({
7080
7191
  new Promise((resolve2) => setTimeout(() => resolve2(null), probeTimeoutMs))
7081
7192
  ]);
7082
7193
  if (!r) return degraded;
7194
+ const installed = Boolean(r?.installed);
7195
+ const authenticated = Boolean(r?.authenticated);
7196
+ const authTier = resolveReportedAuthTier({ authTier: r?.authTier, installed, authenticated });
7083
7197
  return {
7084
7198
  agent,
7085
- installed: Boolean(r?.installed),
7086
- authenticated: Boolean(r?.authenticated),
7087
- ...typeof r?.version === "string" && r.version ? { version: r.version } : {}
7199
+ installed,
7200
+ authenticated,
7201
+ ...typeof r?.version === "string" && r.version ? { version: r.version } : {},
7202
+ // Omitted when unknown, which is what an older daemon's silence already
7203
+ // means — the control-plane schema resolves BOTH to 'unknown'. Never
7204
+ // invent a tier to fill the gap.
7205
+ ...authTier !== AUTH_TIER_UNKNOWN ? { auth_tier: authTier } : {}
7088
7206
  };
7089
7207
  } catch {
7090
7208
  return { agent, installed: false, authenticated: false };
@@ -7147,6 +7265,7 @@ var init_agent_availability = __esm({
7147
7265
  "use strict";
7148
7266
  init_resolve_runner();
7149
7267
  init_agent_auth_probe_process();
7268
+ init_agent_auth_tier();
7150
7269
  DEFAULT_TTL_MS = 5 * 60 * 1e3;
7151
7270
  PROBE_TIMEOUT_MS = 1e4;
7152
7271
  }
@@ -7273,26 +7392,183 @@ var init_local_model_remote_config = __esm({
7273
7392
  }
7274
7393
  });
7275
7394
 
7276
- // ../../scripts/virtual-office/code-runner/account-usage.mjs
7277
- import { spawn as spawn4 } from "node:child_process";
7395
+ // ../../scripts/virtual-office/code-runner/account-usage/shared.mjs
7396
+ import crypto from "node:crypto";
7278
7397
  import fs6 from "node:fs";
7398
+ function accountKey(agent, rawId) {
7399
+ const id = typeof rawId === "string" ? rawId.trim() : "";
7400
+ if (!id) return null;
7401
+ try {
7402
+ return crypto.scryptSync(`${agent}:${id}`, ACCOUNT_KEY_SALT, 8).toString("hex");
7403
+ } catch {
7404
+ return null;
7405
+ }
7406
+ }
7407
+ function makeUsageRow({
7408
+ agent,
7409
+ sevenDay,
7410
+ fiveHour,
7411
+ monthly,
7412
+ source,
7413
+ capturedAt,
7414
+ accountId,
7415
+ sevenDayResetsAt,
7416
+ fiveHourResetsAt,
7417
+ monthlyResetsAt
7418
+ }) {
7419
+ const seven = clampPct(sevenDay);
7420
+ const five = clampPct(fiveHour);
7421
+ const month = clampPct(monthly);
7422
+ if (seven === null && five === null && month === null) return null;
7423
+ const row = {
7424
+ agent,
7425
+ seven_day_used_pct: seven,
7426
+ five_hour_used_pct: five,
7427
+ source
7428
+ };
7429
+ if (month !== null) row.monthly_used_pct = month;
7430
+ if (typeof monthlyResetsAt === "string" && monthlyResetsAt) {
7431
+ row.monthly_resets_at = monthlyResetsAt;
7432
+ }
7433
+ if (typeof capturedAt === "string" && capturedAt) row.captured_at = capturedAt;
7434
+ const key = accountKey(agent, accountId);
7435
+ if (key) row.account_key = key;
7436
+ if (typeof sevenDayResetsAt === "string" && sevenDayResetsAt) {
7437
+ row.seven_day_resets_at = sevenDayResetsAt;
7438
+ }
7439
+ if (typeof fiveHourResetsAt === "string" && fiveHourResetsAt) {
7440
+ row.five_hour_resets_at = fiveHourResetsAt;
7441
+ }
7442
+ return row;
7443
+ }
7444
+ var clampPct, readJson, ACCOUNT_KEY_SALT;
7445
+ var init_shared = __esm({
7446
+ "../../scripts/virtual-office/code-runner/account-usage/shared.mjs"() {
7447
+ "use strict";
7448
+ clampPct = (v) => {
7449
+ const n = typeof v === "number" ? v : typeof v === "string" && v.trim() !== "" ? Number(v) : NaN;
7450
+ return Number.isFinite(n) ? Math.min(100, Math.max(0, Math.round(n))) : null;
7451
+ };
7452
+ readJson = (p) => {
7453
+ try {
7454
+ return JSON.parse(fs6.readFileSync(p, "utf8"));
7455
+ } catch {
7456
+ return null;
7457
+ }
7458
+ };
7459
+ ACCOUNT_KEY_SALT = "algohq/account-usage/v1";
7460
+ }
7461
+ });
7462
+
7463
+ // ../../scripts/virtual-office/code-runner/account-usage/claude.mjs
7279
7464
  import os3 from "node:os";
7280
7465
  import path14 from "node:path";
7281
- function snapshotAgeMs(payload, filePath, now, mtimeMs) {
7282
- const iso = typeof payload?.capturedAt === "string" ? payload.capturedAt : null;
7283
- if (iso) {
7284
- const capturedMs = new Date(iso).getTime();
7285
- if (Number.isFinite(capturedMs)) return now - capturedMs;
7466
+ function usageBaseUrl(env2 = process.env) {
7467
+ const raw = env2.ANTHROPIC_BASE_URL || "https://api.anthropic.com";
7468
+ return String(raw).replace(/\/+$/, "");
7469
+ }
7470
+ function readOAuthToken({ homeDir = os3.homedir(), read = readJson, now = Date.now() } = {}) {
7471
+ const creds = read(path14.join(homeDir, ".claude", ".credentials.json"));
7472
+ const oauth = creds && typeof creds === "object" ? creds.claudeAiOauth : null;
7473
+ if (!oauth || typeof oauth !== "object") return null;
7474
+ const token2 = typeof oauth.accessToken === "string" ? oauth.accessToken.trim() : "";
7475
+ if (!token2) return null;
7476
+ const expiresAt = Number(oauth.expiresAt);
7477
+ if (Number.isFinite(expiresAt) && expiresAt > 0 && expiresAt <= now) return null;
7478
+ return token2;
7479
+ }
7480
+ function readAccountId({ homeDir = os3.homedir(), read = readJson } = {}) {
7481
+ const cfg = read(path14.join(homeDir, ".claude.json"));
7482
+ const account = cfg && typeof cfg === "object" ? cfg.oauthAccount : null;
7483
+ return account && typeof account.accountUuid === "string" ? account.accountUuid : null;
7484
+ }
7485
+ function entryPct(entry) {
7486
+ if (!entry || typeof entry !== "object") return null;
7487
+ for (const field of ["used_percentage", "utilization", "percent"]) {
7488
+ const pct = clampPct(entry[field]);
7489
+ if (pct !== null) return pct;
7286
7490
  }
7287
- const fileMs = mtimeMs(filePath);
7288
- return Number.isFinite(fileMs) ? now - fileMs : null;
7491
+ return null;
7492
+ }
7493
+ function entryResetsAt(entry) {
7494
+ if (!entry || typeof entry !== "object") return null;
7495
+ for (const field of ["resets_at", "reset_at", "resetsAt"]) {
7496
+ const value = entry[field];
7497
+ if (typeof value === "string" && value) return value;
7498
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
7499
+ return new Date(value * 1e3).toISOString();
7500
+ }
7501
+ }
7502
+ return null;
7503
+ }
7504
+ function parseOAuthUsage(body) {
7505
+ if (!body || typeof body !== "object") return null;
7506
+ let fiveHour = null;
7507
+ let sevenDay = null;
7508
+ const list = Array.isArray(body) ? body : Array.isArray(body.limits) ? body.limits : null;
7509
+ if (list) {
7510
+ for (const entry of list) {
7511
+ const kind = entry && typeof entry.kind === "string" ? entry.kind : "";
7512
+ if ((kind === "five_hour" || kind === "session") && !fiveHour) fiveHour = entry;
7513
+ else if ((kind === "seven_day" || kind === "weekly_all") && !sevenDay) sevenDay = entry;
7514
+ }
7515
+ }
7516
+ if (!fiveHour && body.five_hour) fiveHour = body.five_hour;
7517
+ if (!sevenDay && body.seven_day) sevenDay = body.seven_day;
7518
+ const five = entryPct(fiveHour);
7519
+ const seven = entryPct(sevenDay);
7520
+ if (five === null && seven === null) return null;
7521
+ return {
7522
+ five_hour_used_pct: five,
7523
+ seven_day_used_pct: seven,
7524
+ five_hour_resets_at: entryResetsAt(fiveHour),
7525
+ seven_day_resets_at: entryResetsAt(sevenDay)
7526
+ };
7289
7527
  }
7290
- function readClaudeUsage({
7528
+ async function readClaudeOAuthUsage({
7529
+ fetchImpl = fetch,
7530
+ env: env2 = process.env,
7531
+ timeoutMs = DEFAULT_TIMEOUT_MS,
7291
7532
  homeDir = os3.homedir(),
7292
- read: rawRead = readJson,
7293
- now = Date.now(),
7294
- mtimeMs = mtimeMsOf
7533
+ read = readJson,
7534
+ now = () => Date.now()
7295
7535
  } = {}) {
7536
+ const token2 = readOAuthToken({ homeDir, read, now: now() });
7537
+ if (!token2) return null;
7538
+ const controller = new AbortController();
7539
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
7540
+ try {
7541
+ const res = await fetchImpl(`${usageBaseUrl(env2)}${USAGE_PATH}`, {
7542
+ method: "GET",
7543
+ headers: {
7544
+ authorization: `Bearer ${token2}`,
7545
+ "anthropic-beta": OAUTH_BETA,
7546
+ "content-type": "application/json",
7547
+ accept: "application/json"
7548
+ },
7549
+ signal: controller.signal
7550
+ });
7551
+ if (!res || !res.ok) return null;
7552
+ const parsed = parseOAuthUsage(await res.json());
7553
+ if (!parsed) return null;
7554
+ return makeUsageRow({
7555
+ agent: "claude",
7556
+ source: "oauth",
7557
+ // The response describes the account AS OF NOW, so the reading time is now.
7558
+ capturedAt: new Date(now()).toISOString(),
7559
+ accountId: readAccountId({ homeDir, read }),
7560
+ sevenDay: parsed.seven_day_used_pct,
7561
+ fiveHour: parsed.five_hour_used_pct,
7562
+ sevenDayResetsAt: parsed.seven_day_resets_at,
7563
+ fiveHourResetsAt: parsed.five_hour_resets_at
7564
+ });
7565
+ } catch {
7566
+ return null;
7567
+ } finally {
7568
+ clearTimeout(timer);
7569
+ }
7570
+ }
7571
+ function readClaudeFileUsage({ homeDir = os3.homedir(), read: rawRead = readJson } = {}) {
7296
7572
  const read = (p) => {
7297
7573
  try {
7298
7574
  return rawRead(p);
@@ -7300,55 +7576,89 @@ function readClaudeUsage({
7300
7576
  return null;
7301
7577
  }
7302
7578
  };
7303
- const statusPath = path14.join(homeDir, ".claude", "claude-usage.json");
7304
- const status = read(statusPath);
7305
- if (status && (status.seven_day || status.five_hour) && isFresh(snapshotAgeMs(status, statusPath, now, mtimeMs))) {
7306
- const entry = {
7579
+ const accountId = readAccountId({ homeDir, read });
7580
+ const status = read(path14.join(homeDir, ".claude", "claude-usage.json"));
7581
+ if (status && (status.seven_day || status.five_hour)) {
7582
+ const row = makeUsageRow({
7307
7583
  agent: "claude",
7308
- seven_day_used_pct: clampPct(status.seven_day?.used_percentage),
7309
- five_hour_used_pct: clampPct(status.five_hour?.used_percentage)
7310
- };
7311
- if (entry.seven_day_used_pct !== null || entry.five_hour_used_pct !== null) return entry;
7584
+ source: "statusline",
7585
+ capturedAt: typeof status.capturedAt === "string" ? status.capturedAt : null,
7586
+ accountId,
7587
+ sevenDay: status.seven_day?.used_percentage,
7588
+ fiveHour: status.five_hour?.used_percentage,
7589
+ sevenDayResetsAt: status.seven_day?.resets_at ?? null,
7590
+ fiveHourResetsAt: status.five_hour?.resets_at ?? null
7591
+ });
7592
+ if (row) return row;
7312
7593
  }
7313
- const weeklyPath = path14.join(homeDir, ".claude", "claude-weekly-usage.json");
7314
- const weekly = read(weeklyPath);
7315
- if (weekly && isFresh(snapshotAgeMs(weekly, weeklyPath, now, mtimeMs))) {
7316
- const entry = {
7594
+ const weekly = read(path14.join(homeDir, ".claude", "claude-weekly-usage.json"));
7595
+ if (weekly) {
7596
+ const row = makeUsageRow({
7317
7597
  agent: "claude",
7318
- seven_day_used_pct: clampPct(weekly.sevenDayPct),
7319
- five_hour_used_pct: clampPct(weekly.fiveHourPct)
7320
- };
7321
- if (entry.seven_day_used_pct !== null || entry.five_hour_used_pct !== null) return entry;
7598
+ source: "file",
7599
+ capturedAt: typeof weekly.capturedAt === "string" ? weekly.capturedAt : null,
7600
+ accountId,
7601
+ sevenDay: weekly.sevenDayPct,
7602
+ fiveHour: weekly.fiveHourPct,
7603
+ sevenDayResetsAt: weekly.sevenDayResetsAt ?? null
7604
+ });
7605
+ if (row) return row;
7322
7606
  }
7323
7607
  return null;
7324
7608
  }
7325
- function collectAccountUsage(opts = {}) {
7326
- const claude = readClaudeUsage(opts);
7327
- return claude ? [claude] : [];
7609
+ async function readClaudeUsage(opts = {}) {
7610
+ try {
7611
+ const live = await readClaudeOAuthUsage(opts);
7612
+ if (live) return live;
7613
+ } catch {
7614
+ }
7615
+ return readClaudeFileUsage(opts);
7328
7616
  }
7617
+ var USAGE_PATH, OAUTH_BETA, DEFAULT_TIMEOUT_MS;
7618
+ var init_claude = __esm({
7619
+ "../../scripts/virtual-office/code-runner/account-usage/claude.mjs"() {
7620
+ "use strict";
7621
+ init_shared();
7622
+ USAGE_PATH = "/api/oauth/usage";
7623
+ OAUTH_BETA = "oauth-2025-04-20";
7624
+ DEFAULT_TIMEOUT_MS = 5e3;
7625
+ }
7626
+ });
7627
+
7628
+ // ../../scripts/virtual-office/code-runner/account-usage/codex.mjs
7629
+ import { spawn as spawn4 } from "node:child_process";
7329
7630
  function weeklyWindow(snapshot2) {
7330
7631
  if (!snapshot2 || typeof snapshot2 !== "object") return null;
7331
7632
  const windows = [snapshot2.primary, snapshot2.secondary].filter(Boolean);
7332
7633
  return windows.find((window) => Number(window?.windowDurationMins) === 7 * 24 * 60) ?? windows.find((window) => Number(window?.windowDurationMins) >= 6 * 24 * 60) ?? null;
7333
7634
  }
7334
- function parseCodexUsage(response) {
7635
+ function resetsAtIso(window) {
7636
+ const raw = Number(window?.resetsAt);
7637
+ if (!Number.isFinite(raw) || raw <= 0) return null;
7638
+ return new Date(raw * 1e3).toISOString();
7639
+ }
7640
+ function parseCodexUsage(response, { now = () => Date.now() } = {}) {
7335
7641
  const result = response?.result;
7336
7642
  const snapshot2 = result?.rateLimitsByLimitId?.codex ?? result?.rateLimits;
7337
7643
  const weekly = weeklyWindow(snapshot2);
7338
7644
  const used = clampPct(weekly?.usedPercent);
7339
7645
  if (used === null) return null;
7340
- return {
7646
+ return makeUsageRow({
7341
7647
  agent: "codex",
7342
- seven_day_used_pct: used,
7343
- five_hour_used_pct: null
7344
- };
7648
+ source: "app-server",
7649
+ capturedAt: new Date(now()).toISOString(),
7650
+ sevenDay: used,
7651
+ fiveHour: null,
7652
+ sevenDayResetsAt: resetsAtIso(weekly)
7653
+ });
7345
7654
  }
7346
7655
  function readCodexUsage({
7347
7656
  spawnImpl = spawn4,
7348
7657
  resolveBinary = resolveCodexBinary,
7349
7658
  timeoutMs = 8e3,
7350
7659
  env: env2 = process.env,
7351
- platform = process.platform
7660
+ platform = process.platform,
7661
+ now = () => Date.now()
7352
7662
  } = {}) {
7353
7663
  return new Promise((resolve2) => {
7354
7664
  let child;
@@ -7370,7 +7680,8 @@ function readCodexUsage({
7370
7680
  child = spawnImpl(binary, ["app-server", "--stdio"], {
7371
7681
  env: env2,
7372
7682
  windowsHide: true,
7373
- shell: platform === "win32" && !/\.exe$/iu.test(String(binary)),
7683
+ shell: false,
7684
+ windowsVerbatimArguments: false,
7374
7685
  stdio: ["pipe", "pipe", "ignore"]
7375
7686
  });
7376
7687
  child.on("error", () => finish(null));
@@ -7394,7 +7705,7 @@ function readCodexUsage({
7394
7705
  child.stdin?.write(`${JSON.stringify({ method: "account/rateLimits/read", id: 2 })}
7395
7706
  `);
7396
7707
  } else if (message?.id === 2) {
7397
- finish(parseCodexUsage(message));
7708
+ finish(parseCodexUsage(message, { now }));
7398
7709
  }
7399
7710
  }
7400
7711
  });
@@ -7412,14 +7723,108 @@ function readCodexUsage({
7412
7723
  }
7413
7724
  });
7414
7725
  }
7415
- async function collectConnectedAccountUsage({ readCodex = readCodexUsage, ...claudeOptions } = {}) {
7416
- const claude = readClaudeUsage(claudeOptions);
7417
- let codex = null;
7418
- try {
7419
- codex = await readCodex();
7420
- } catch {
7726
+ var init_codex = __esm({
7727
+ "../../scripts/virtual-office/code-runner/account-usage/codex.mjs"() {
7728
+ "use strict";
7729
+ init_shared();
7730
+ init_codex_runner();
7731
+ }
7732
+ });
7733
+
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";
7421
7808
  }
7422
- return [claude, codex].filter(Boolean);
7809
+ });
7810
+
7811
+ // ../../scripts/virtual-office/code-runner/account-usage/index.mjs
7812
+ function collectAccountUsage(opts = {}) {
7813
+ const claude = readClaudeFileUsage(opts);
7814
+ return claude ? [claude] : [];
7815
+ }
7816
+ async function collectConnectedAccountUsage({
7817
+ readClaude = readClaudeUsage,
7818
+ readCodex = readCodexUsage,
7819
+ readCopilot = readCopilotUsage,
7820
+ ...agentOptions
7821
+ } = {}) {
7822
+ const settled = await Promise.allSettled([
7823
+ readClaude(agentOptions),
7824
+ readCodex(agentOptions),
7825
+ readCopilot(agentOptions)
7826
+ ]);
7827
+ return settled.map((outcome) => outcome.status === "fulfilled" ? outcome.value : null).filter(Boolean);
7423
7828
  }
7424
7829
  function makeAccountUsageProvider({
7425
7830
  ttlMs = DEFAULT_TTL_MS2,
@@ -7447,35 +7852,33 @@ function makeAccountUsageProvider({
7447
7852
  }
7448
7853
  };
7449
7854
  }
7450
- var clampPct, readJson, STALE_AFTER_MS, mtimeMsOf, isFresh, DEFAULT_TTL_MS2;
7855
+ var AGENT_USAGE_CAPABILITY, DEFAULT_TTL_MS2;
7451
7856
  var init_account_usage = __esm({
7452
- "../../scripts/virtual-office/code-runner/account-usage.mjs"() {
7857
+ "../../scripts/virtual-office/code-runner/account-usage/index.mjs"() {
7453
7858
  "use strict";
7454
- init_codex_runner();
7455
- clampPct = (v) => {
7456
- const n = Number(v);
7457
- return Number.isFinite(n) ? Math.min(100, Math.max(0, Math.round(n))) : null;
7458
- };
7459
- readJson = (p) => {
7460
- try {
7461
- return JSON.parse(fs6.readFileSync(p, "utf8"));
7462
- } catch {
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;
7859
+ init_claude();
7860
+ init_codex();
7861
+ init_copilot();
7862
+ init_shared();
7863
+ AGENT_USAGE_CAPABILITY = Object.freeze({
7864
+ claude: Object.freeze({ five_hour: true, seven_day: true, monthly: false }),
7865
+ codex: Object.freeze({ five_hour: false, seven_day: true, monthly: false }),
7866
+ copilot: Object.freeze({ five_hour: false, seven_day: false, monthly: true }),
7867
+ cursor: Object.freeze({ five_hour: false, seven_day: false, monthly: false }),
7868
+ gemini: Object.freeze({ five_hour: false, seven_day: false, monthly: false })
7869
+ });
7475
7870
  DEFAULT_TTL_MS2 = 5 * 60 * 1e3;
7476
7871
  }
7477
7872
  });
7478
7873
 
7874
+ // ../../scripts/virtual-office/code-runner/account-usage.mjs
7875
+ var init_account_usage2 = __esm({
7876
+ "../../scripts/virtual-office/code-runner/account-usage.mjs"() {
7877
+ "use strict";
7878
+ init_account_usage();
7879
+ }
7880
+ });
7881
+
7479
7882
  // ../../scripts/virtual-office/code-runner/ci-repair-evidence.mjs
7480
7883
  function extractWorkflowRunIds(links = []) {
7481
7884
  const ids = [];
@@ -8268,7 +8671,6 @@ function makeWatchRunner({
8268
8671
  repairAttempt: chain.attempt + 1
8269
8672
  }),
8270
8673
  ...operatorId && operatorId !== "admin" ? { on_behalf_of_operator_id: operatorId } : {},
8271
- agent: "claude",
8272
8674
  dispatch_mode: "fast",
8273
8675
  max_turns: 80,
8274
8676
  max_budget_usd: chain.per_attempt_budget_usd,
@@ -10180,7 +10582,15 @@ var init_agent_process_env = __esm({
10180
10582
  "WINDIR",
10181
10583
  "VO_RUNNER_PREFER_LOGIN",
10182
10584
  "VO_RUNNER_CLAUDE_PREFER_LOGIN",
10183
- "VO_RUNNER_CODEX_PREFER_LOGIN"
10585
+ "VO_RUNNER_CODEX_PREFER_LOGIN",
10586
+ // The tier-1 opt-out (PR #9242). Auth-preference flags are only visible to a
10587
+ // runner's applyAuthEnv() if they are listed HERE: the daemon builds the child
10588
+ // env with buildAgentProcessEnv(process.env) (code-runner-daemon.mjs:117), so
10589
+ // anything absent from this set is stripped before withAnthropicKey ever sees
10590
+ // it. #9242 added VO_RUNNER_PREFER_KEY without this line, which left the
10591
+ // escape hatch inert — an operator who set it still got the subscription.
10592
+ "VO_RUNNER_PREFER_KEY",
10593
+ "VO_RUNNER_CLAUDE_PREFER_KEY"
10184
10594
  ]);
10185
10595
  }
10186
10596
  });
@@ -12444,7 +12854,7 @@ var init_code_runner_daemon = __esm({
12444
12854
  init_runner_capacity();
12445
12855
  init_agent_availability();
12446
12856
  init_local_model_remote_config();
12447
- init_account_usage();
12857
+ init_account_usage2();
12448
12858
  init_pr_watcher();
12449
12859
  init_existing_pr_target();
12450
12860
  init_watch_cycle_coordinator();