claude-use 11.15.0 → 11.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +415 -282
- package/dist/index.cjs +9 -13
- package/dist/index.mjs +9 -13
- package/dist/types/index.d.ts +2 -12
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -26906,7 +26906,7 @@ function isTimeZone(name) {
|
|
|
26906
26906
|
return false;
|
|
26907
26907
|
}
|
|
26908
26908
|
}
|
|
26909
|
-
var import_node_path4, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_TIERS, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_MODEL, ANTIGRAVITY_DEFAULT_TIER_MODELS, ANTIGRAVITY_DEFAULT_EFFORT, AntigravityProviderConfigSchema, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
26909
|
+
var import_node_path4, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_TIERS, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_MODEL, ANTIGRAVITY_DEFAULT_TIER_MODELS, ANTIGRAVITY_DEFAULT_EFFORT, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
26910
26910
|
var init_schema = __esm({
|
|
26911
26911
|
"src/config/schema.ts"() {
|
|
26912
26912
|
"use strict";
|
|
@@ -27012,24 +27012,20 @@ var init_schema = __esm({
|
|
|
27012
27012
|
ANTIGRAVITY_DEFAULT_MODE = "cloud";
|
|
27013
27013
|
ANTIGRAVITY_DEFAULT_MODEL = "gemini-3.8-flash-high";
|
|
27014
27014
|
ANTIGRAVITY_DEFAULT_TIER_MODELS = Object.freeze({
|
|
27015
|
-
fable: "gemini-3.8-flash-high",
|
|
27016
|
-
opus: "gemini-3.8-flash-high",
|
|
27017
|
-
sonnet: "gemini-3.8-flash-medium",
|
|
27018
|
-
haiku: "gemini-3.8-flash-low"
|
|
27015
|
+
fable: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
|
|
27016
|
+
opus: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
|
|
27017
|
+
sonnet: ["claude-sonnet-5-5-medium", "gemini-4-argon-medium", "gemini-3.8-flash-medium"],
|
|
27018
|
+
haiku: ["gemini-3.8-flash-low", "gemini-4-argon-low", "gpt-oss-120b-medium"]
|
|
27019
27019
|
});
|
|
27020
27020
|
ANTIGRAVITY_DEFAULT_EFFORT = "low";
|
|
27021
|
+
AntigravityModelTargetSchema = external_exports.union([external_exports.string().min(1), external_exports.array(external_exports.string().min(1)).min(1)]);
|
|
27021
27022
|
AntigravityProviderConfigSchema = external_exports.strictObject({
|
|
27022
27023
|
/** Operational mode: direct cloud endpoint or local ACP daemon. Defaults to `cloud`. */
|
|
27023
27024
|
mode: external_exports.enum(ANTIGRAVITY_MODES).optional(),
|
|
27024
27025
|
/** The model a request maps to when no tier matches its model name. */
|
|
27025
27026
|
defaultModel: external_exports.string().min(1).optional(),
|
|
27026
|
-
/**
|
|
27027
|
-
models: external_exports.
|
|
27028
|
-
fable: external_exports.string().min(1).optional(),
|
|
27029
|
-
opus: external_exports.string().min(1).optional(),
|
|
27030
|
-
sonnet: external_exports.string().min(1).optional(),
|
|
27031
|
-
haiku: external_exports.string().min(1).optional()
|
|
27032
|
-
}).optional(),
|
|
27027
|
+
/** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
|
|
27028
|
+
models: external_exports.record(external_exports.string().min(1), AntigravityModelTargetSchema).optional(),
|
|
27033
27029
|
/** The reasoning effort used when the request's own effort is not one the backend accepts. */
|
|
27034
27030
|
effort: external_exports.enum(ANTIGRAVITY_EFFORTS).optional(),
|
|
27035
27031
|
/** Cloud-specific settings (for `mode: "cloud"`). */
|
|
@@ -34093,7 +34089,7 @@ var init_package = __esm({
|
|
|
34093
34089
|
"package.json"() {
|
|
34094
34090
|
package_default = {
|
|
34095
34091
|
name: "claude-use",
|
|
34096
|
-
version: "11.
|
|
34092
|
+
version: "11.17.0",
|
|
34097
34093
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
34098
34094
|
license: "MIT",
|
|
34099
34095
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -127771,6 +127767,256 @@ function translateRequest(body, config2) {
|
|
|
127771
127767
|
// src/antigravity/translate.ts
|
|
127772
127768
|
var import_node_crypto21 = require("node:crypto");
|
|
127773
127769
|
|
|
127770
|
+
// src/antigravity/quota.ts
|
|
127771
|
+
init_cloudUpstream();
|
|
127772
|
+
var MS_PER_SECOND8 = 1e3;
|
|
127773
|
+
var DEFAULT_RETRY_AFTER_SECONDS = 60;
|
|
127774
|
+
var FRACTION_DIGITS = 3;
|
|
127775
|
+
var GEMINI_5H_KEYS = ["gemini-5h", "gemini_5h", "gemini"];
|
|
127776
|
+
var GEMINI_WEEKLY_KEYS = ["gemini-weekly", "gemini_weekly"];
|
|
127777
|
+
var ARGON_WEEKLY_KEYS = ["gemini-argon-wtu-weekly"];
|
|
127778
|
+
var THIRD_PARTY_5H_KEYS = ["3p-5h", "claude-5h", "3p_5h", "claude_5h", "claude"];
|
|
127779
|
+
var THIRD_PARTY_WEEKLY_KEYS = ["3p-weekly", "claude-weekly", "3p_weekly", "claude_weekly"];
|
|
127780
|
+
function findBucket(quota, keys) {
|
|
127781
|
+
for (const key of keys) {
|
|
127782
|
+
const bucket = quota[key];
|
|
127783
|
+
if (bucket !== void 0) {
|
|
127784
|
+
return bucket;
|
|
127785
|
+
}
|
|
127786
|
+
}
|
|
127787
|
+
return void 0;
|
|
127788
|
+
}
|
|
127789
|
+
var QUOTA_FAMILY_WINDOWS = [
|
|
127790
|
+
{ label: "Gem 5h", keys: GEMINI_5H_KEYS },
|
|
127791
|
+
{ label: "Gem Wk", keys: GEMINI_WEEKLY_KEYS },
|
|
127792
|
+
{ label: "3P 5h", keys: THIRD_PARTY_5H_KEYS },
|
|
127793
|
+
{ label: "3P Wk", keys: THIRD_PARTY_WEEKLY_KEYS },
|
|
127794
|
+
{ label: "Argon Wk", keys: ARGON_WEEKLY_KEYS }
|
|
127795
|
+
];
|
|
127796
|
+
function antigravityFamilyBuckets(quota) {
|
|
127797
|
+
return QUOTA_FAMILY_WINDOWS.flatMap(({ label, keys }) => {
|
|
127798
|
+
const bucket = findBucket(quota, keys);
|
|
127799
|
+
return bucket === void 0 ? [] : [{ label, bucket }];
|
|
127800
|
+
});
|
|
127801
|
+
}
|
|
127802
|
+
function selectAntigravityBuckets(quota, model) {
|
|
127803
|
+
const lower = (model ?? "").toLowerCase();
|
|
127804
|
+
if (lower.includes("argon")) {
|
|
127805
|
+
return { fiveHour: void 0, weekly: findBucket(quota, ARGON_WEEKLY_KEYS) };
|
|
127806
|
+
}
|
|
127807
|
+
const isGemini = lower.includes("gemini");
|
|
127808
|
+
return {
|
|
127809
|
+
fiveHour: findBucket(quota, isGemini ? GEMINI_5H_KEYS : THIRD_PARTY_5H_KEYS),
|
|
127810
|
+
weekly: findBucket(quota, isGemini ? GEMINI_WEEKLY_KEYS : THIRD_PARTY_WEEKLY_KEYS)
|
|
127811
|
+
};
|
|
127812
|
+
}
|
|
127813
|
+
var SECONDS_PER_HOUR2 = 3600;
|
|
127814
|
+
var HOURS_PER_FIVE_HOUR_WINDOW = 5;
|
|
127815
|
+
var DAYS_PER_WEEK2 = 7;
|
|
127816
|
+
var HOURS_PER_DAY5 = 24;
|
|
127817
|
+
var FIVE_HOUR_PERIOD_SECONDS = HOURS_PER_FIVE_HOUR_WINDOW * SECONDS_PER_HOUR2;
|
|
127818
|
+
var WEEK_PERIOD_SECONDS = DAYS_PER_WEEK2 * HOURS_PER_DAY5 * SECONDS_PER_HOUR2;
|
|
127819
|
+
function windowPressure(bucket, periodSeconds) {
|
|
127820
|
+
const remaining = bucket?.remaining_fraction;
|
|
127821
|
+
const resetIn = bucket?.reset_in_seconds;
|
|
127822
|
+
if (remaining === void 0 || resetIn === void 0 || !Number.isFinite(remaining) || !Number.isFinite(resetIn)) {
|
|
127823
|
+
return void 0;
|
|
127824
|
+
}
|
|
127825
|
+
const periodLeft = Math.min(1, Math.max(resetIn, 1) / periodSeconds);
|
|
127826
|
+
return Math.max(0, remaining) / periodLeft;
|
|
127827
|
+
}
|
|
127828
|
+
function antigravityQuotaPressure(quota, model) {
|
|
127829
|
+
const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
|
|
127830
|
+
const pressures = [windowPressure(fiveHour, FIVE_HOUR_PERIOD_SECONDS), windowPressure(weekly, WEEK_PERIOD_SECONDS)].filter((pressure) => pressure !== void 0);
|
|
127831
|
+
return pressures.length === 0 ? void 0 : Math.min(...pressures);
|
|
127832
|
+
}
|
|
127833
|
+
function calculateUtilization(remainingFraction) {
|
|
127834
|
+
if (remainingFraction === void 0 || !Number.isFinite(remainingFraction)) {
|
|
127835
|
+
return void 0;
|
|
127836
|
+
}
|
|
127837
|
+
const clampedRem = Math.max(0, Math.min(1, remainingFraction));
|
|
127838
|
+
const used = Math.max(0, 1 - clampedRem);
|
|
127839
|
+
return used.toFixed(FRACTION_DIGITS);
|
|
127840
|
+
}
|
|
127841
|
+
function calculateResetTimestamp(nowSec, resetInSeconds) {
|
|
127842
|
+
if (resetInSeconds === void 0 || !Number.isFinite(resetInSeconds) || resetInSeconds < 0) {
|
|
127843
|
+
return void 0;
|
|
127844
|
+
}
|
|
127845
|
+
return String(nowSec + Math.ceil(resetInSeconds));
|
|
127846
|
+
}
|
|
127847
|
+
function parseRetryAfterSeconds(raw, defaultSeconds = DEFAULT_RETRY_AFTER_SECONDS) {
|
|
127848
|
+
if (raw === null || raw === void 0 || raw.trim() === "") {
|
|
127849
|
+
return defaultSeconds;
|
|
127850
|
+
}
|
|
127851
|
+
const numeric = Number(raw);
|
|
127852
|
+
if (Number.isFinite(numeric) && numeric > 0) {
|
|
127853
|
+
return Math.ceil(numeric);
|
|
127854
|
+
}
|
|
127855
|
+
const parsedDate = Date.parse(raw);
|
|
127856
|
+
if (!Number.isNaN(parsedDate)) {
|
|
127857
|
+
const diffSec = Math.ceil((parsedDate - Date.now()) / MS_PER_SECOND8);
|
|
127858
|
+
return Math.max(1, diffSec);
|
|
127859
|
+
}
|
|
127860
|
+
return defaultSeconds;
|
|
127861
|
+
}
|
|
127862
|
+
function unifiedAntigravityQuotaHeaders(params) {
|
|
127863
|
+
const rejected = params.rejected === true;
|
|
127864
|
+
const nowSec = Math.floor(params.nowMs / MS_PER_SECOND8);
|
|
127865
|
+
const { fiveHour: b5h, weekly: bWk } = selectAntigravityBuckets(params.quota ?? {}, params.model);
|
|
127866
|
+
const used5h = calculateUtilization(b5h?.remaining_fraction);
|
|
127867
|
+
const reset5h = calculateResetTimestamp(nowSec, b5h?.reset_in_seconds);
|
|
127868
|
+
const used7d = calculateUtilization(bWk?.remaining_fraction);
|
|
127869
|
+
const reset7d = calculateResetTimestamp(nowSec, bWk?.reset_in_seconds);
|
|
127870
|
+
const exhaustion = rejected ? antigravityQuotaExhaustion(params.quota, params.model, params.nowMs) : void 0;
|
|
127871
|
+
if (rejected && exhaustion === void 0) {
|
|
127872
|
+
return {};
|
|
127873
|
+
}
|
|
127874
|
+
if (!rejected && used5h === void 0 && reset5h === void 0 && used7d === void 0 && reset7d === void 0) {
|
|
127875
|
+
return {};
|
|
127876
|
+
}
|
|
127877
|
+
const headers = {
|
|
127878
|
+
"anthropic-ratelimit-unified-status": rejected ? "rejected" : "allowed"
|
|
127879
|
+
};
|
|
127880
|
+
let earliestResetSec;
|
|
127881
|
+
if (used5h !== void 0 && reset5h !== void 0) {
|
|
127882
|
+
headers["anthropic-ratelimit-unified-5h-utilization"] = used5h;
|
|
127883
|
+
headers["anthropic-ratelimit-unified-5h-reset"] = reset5h;
|
|
127884
|
+
earliestResetSec = Number(reset5h);
|
|
127885
|
+
if (rejected) {
|
|
127886
|
+
headers["anthropic-ratelimit-unified-5h-status"] = exhaustion?.exhaustedWindows.includes("five_hour") === true ? "rejected" : "allowed";
|
|
127887
|
+
}
|
|
127888
|
+
}
|
|
127889
|
+
if (used7d !== void 0 && reset7d !== void 0) {
|
|
127890
|
+
headers["anthropic-ratelimit-unified-7d-utilization"] = used7d;
|
|
127891
|
+
headers["anthropic-ratelimit-unified-7d-reset"] = reset7d;
|
|
127892
|
+
const reset7dSec = Number(reset7d);
|
|
127893
|
+
earliestResetSec = earliestResetSec === void 0 ? reset7dSec : Math.min(earliestResetSec, reset7dSec);
|
|
127894
|
+
if (rejected) {
|
|
127895
|
+
headers["anthropic-ratelimit-unified-7d-status"] = exhaustion?.exhaustedWindows.includes("seven_day") === true ? "rejected" : "allowed";
|
|
127896
|
+
}
|
|
127897
|
+
}
|
|
127898
|
+
if (exhaustion !== void 0) {
|
|
127899
|
+
headers["anthropic-ratelimit-unified-representative-claim"] = exhaustion.window;
|
|
127900
|
+
headers["anthropic-ratelimit-unified-reset"] = String(exhaustion.resetSec);
|
|
127901
|
+
headers["retry-after"] = String(Math.max(1, exhaustion.resetSec - nowSec));
|
|
127902
|
+
headers["x-should-retry"] = "false";
|
|
127903
|
+
return headers;
|
|
127904
|
+
}
|
|
127905
|
+
if (earliestResetSec !== void 0) {
|
|
127906
|
+
headers["anthropic-ratelimit-unified-reset"] = String(earliestResetSec);
|
|
127907
|
+
}
|
|
127908
|
+
return headers;
|
|
127909
|
+
}
|
|
127910
|
+
function antigravityQuotaExhaustion(quota, model, nowMs) {
|
|
127911
|
+
const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
|
|
127912
|
+
const nowSec = Math.floor(nowMs / MS_PER_SECOND8);
|
|
127913
|
+
const spent = [];
|
|
127914
|
+
for (const [window, bucket] of [["five_hour", fiveHour], ["seven_day", weekly]]) {
|
|
127915
|
+
const remaining = bucket?.remaining_fraction;
|
|
127916
|
+
const resetIn = bucket?.reset_in_seconds;
|
|
127917
|
+
if (remaining !== void 0 && Number.isFinite(remaining) && remaining <= 0 && resetIn !== void 0 && Number.isFinite(resetIn) && resetIn >= 0) {
|
|
127918
|
+
spent.push({ window, resetSec: nowSec + Math.ceil(resetIn) });
|
|
127919
|
+
}
|
|
127920
|
+
}
|
|
127921
|
+
const binding = spent.reduce((latest, next) => latest === void 0 || next.resetSec > latest.resetSec ? next : latest, void 0);
|
|
127922
|
+
return binding === void 0 ? void 0 : { window: binding.window, resetSec: binding.resetSec, exhaustedWindows: spent.map((entry) => entry.window) };
|
|
127923
|
+
}
|
|
127924
|
+
function isRecord8(value2) {
|
|
127925
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
127926
|
+
}
|
|
127927
|
+
function bucketToEntry(bucket, nowMs) {
|
|
127928
|
+
if (!isRecord8(bucket) || typeof bucket.bucketId !== "string") {
|
|
127929
|
+
return void 0;
|
|
127930
|
+
}
|
|
127931
|
+
const remainingFraction = typeof bucket.remainingFraction === "number" && Number.isFinite(bucket.remainingFraction) ? bucket.remainingFraction : void 0;
|
|
127932
|
+
const resetMs = typeof bucket.resetTime === "string" ? Date.parse(bucket.resetTime) : Number.NaN;
|
|
127933
|
+
const resetInSeconds = Number.isNaN(resetMs) ? void 0 : Math.max(0, Math.ceil((resetMs - nowMs) / MS_PER_SECOND8));
|
|
127934
|
+
if (remainingFraction === void 0 && resetInSeconds === void 0) {
|
|
127935
|
+
return void 0;
|
|
127936
|
+
}
|
|
127937
|
+
return {
|
|
127938
|
+
key: bucket.bucketId,
|
|
127939
|
+
entry: {
|
|
127940
|
+
...remainingFraction === void 0 ? {} : { remaining_fraction: remainingFraction },
|
|
127941
|
+
...resetInSeconds === void 0 ? {} : { reset_in_seconds: resetInSeconds }
|
|
127942
|
+
}
|
|
127943
|
+
};
|
|
127944
|
+
}
|
|
127945
|
+
async function fetchAntigravityQuotaSummary(params) {
|
|
127946
|
+
const fetchFn = params.fetchFn ?? fetch;
|
|
127947
|
+
let response;
|
|
127948
|
+
try {
|
|
127949
|
+
response = await fetchFn(`${params.endpoint ?? CCPA_ENDPOINT}/v1internal:retrieveUserQuotaSummary`, {
|
|
127950
|
+
method: "POST",
|
|
127951
|
+
headers: {
|
|
127952
|
+
"Content-Type": "application/json",
|
|
127953
|
+
Authorization: `Bearer ${params.token}`,
|
|
127954
|
+
"User-Agent": CCPA_USER_AGENT
|
|
127955
|
+
},
|
|
127956
|
+
body: JSON.stringify({ project: params.projectId ?? CCPA_DEFAULT_PROJECT_ID })
|
|
127957
|
+
});
|
|
127958
|
+
} catch {
|
|
127959
|
+
return void 0;
|
|
127960
|
+
}
|
|
127961
|
+
if (!response.ok) {
|
|
127962
|
+
return void 0;
|
|
127963
|
+
}
|
|
127964
|
+
let parsed;
|
|
127965
|
+
try {
|
|
127966
|
+
parsed = await response.json();
|
|
127967
|
+
} catch {
|
|
127968
|
+
return void 0;
|
|
127969
|
+
}
|
|
127970
|
+
if (!isRecord8(parsed) || !Array.isArray(parsed.groups)) {
|
|
127971
|
+
return void 0;
|
|
127972
|
+
}
|
|
127973
|
+
const map2 = {};
|
|
127974
|
+
for (const group of parsed.groups) {
|
|
127975
|
+
if (!isRecord8(group) || !Array.isArray(group.buckets)) {
|
|
127976
|
+
continue;
|
|
127977
|
+
}
|
|
127978
|
+
for (const bucket of group.buckets) {
|
|
127979
|
+
const read = bucketToEntry(bucket, params.nowMs);
|
|
127980
|
+
if (read !== void 0) {
|
|
127981
|
+
map2[read.key] = read.entry;
|
|
127982
|
+
}
|
|
127983
|
+
}
|
|
127984
|
+
}
|
|
127985
|
+
return Object.keys(map2).length > 0 ? map2 : void 0;
|
|
127986
|
+
}
|
|
127987
|
+
var ANTIGRAVITY_QUOTA_REFRESH_MS = 6e4;
|
|
127988
|
+
function createCachedAntigravityQuotaSource(params) {
|
|
127989
|
+
let cachedAt = Number.NEGATIVE_INFINITY;
|
|
127990
|
+
let cached2;
|
|
127991
|
+
let readAtMs = Number.NEGATIVE_INFINITY;
|
|
127992
|
+
let refresh;
|
|
127993
|
+
const refreshMs = params.refreshMs ?? ANTIGRAVITY_QUOTA_REFRESH_MS;
|
|
127994
|
+
const run = async () => {
|
|
127995
|
+
const nowMs = params.now();
|
|
127996
|
+
const read = await params.fetchSummary(nowMs);
|
|
127997
|
+
if (read !== void 0) {
|
|
127998
|
+
cached2 = read;
|
|
127999
|
+
readAtMs = nowMs;
|
|
128000
|
+
}
|
|
128001
|
+
cachedAt = params.now();
|
|
128002
|
+
};
|
|
128003
|
+
return () => {
|
|
128004
|
+
const nowMs = params.now();
|
|
128005
|
+
if (nowMs - cachedAt >= refreshMs) {
|
|
128006
|
+
refresh ??= run().finally(() => {
|
|
128007
|
+
refresh = void 0;
|
|
128008
|
+
});
|
|
128009
|
+
}
|
|
128010
|
+
return cached2 === void 0 ? void 0 : ageQuotaMap(cached2, nowMs - readAtMs);
|
|
128011
|
+
};
|
|
128012
|
+
}
|
|
128013
|
+
function ageQuotaMap(quota, elapsedMs) {
|
|
128014
|
+
const elapsedSec = elapsedMs / MS_PER_SECOND8;
|
|
128015
|
+
return Object.fromEntries(
|
|
128016
|
+
Object.entries(quota).map(([key, bucket]) => [key, bucket?.reset_in_seconds === void 0 ? bucket : { ...bucket, reset_in_seconds: Math.max(0, bucket.reset_in_seconds - elapsedSec) }])
|
|
128017
|
+
);
|
|
128018
|
+
}
|
|
128019
|
+
|
|
127774
128020
|
// src/antigravity/signatures.ts
|
|
127775
128021
|
var UNVERIFIED_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
127776
128022
|
var MAX_REMEMBERED = 1024;
|
|
@@ -127790,17 +128036,29 @@ function toolCallSignatureOf(toolUseId) {
|
|
|
127790
128036
|
|
|
127791
128037
|
// src/antigravity/translate.ts
|
|
127792
128038
|
init_schema();
|
|
128039
|
+
function candidatesOf(target) {
|
|
128040
|
+
return typeof target === "string" ? [target] : target;
|
|
128041
|
+
}
|
|
128042
|
+
function isAntigravityTier(key) {
|
|
128043
|
+
return ANTIGRAVITY_TIERS.some((tier) => tier === key);
|
|
128044
|
+
}
|
|
127793
128045
|
function resolveAntigravityConfig(config2) {
|
|
127794
|
-
const overrides = config2?.models;
|
|
128046
|
+
const overrides = config2?.models ?? {};
|
|
128047
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
128048
|
+
for (const [key, target] of Object.entries(overrides)) {
|
|
128049
|
+
if (!isAntigravityTier(key)) {
|
|
128050
|
+
aliases.set(key.toLowerCase(), candidatesOf(target));
|
|
128051
|
+
}
|
|
128052
|
+
}
|
|
128053
|
+
const tierModel = (tier) => {
|
|
128054
|
+
const target = overrides[tier];
|
|
128055
|
+
return target === void 0 ? ANTIGRAVITY_DEFAULT_TIER_MODELS[tier] : candidatesOf(target);
|
|
128056
|
+
};
|
|
127795
128057
|
return {
|
|
127796
128058
|
mode: config2?.mode ?? ANTIGRAVITY_DEFAULT_MODE,
|
|
127797
128059
|
defaultModel: config2?.defaultModel ?? ANTIGRAVITY_DEFAULT_MODEL,
|
|
127798
|
-
models: {
|
|
127799
|
-
|
|
127800
|
-
opus: overrides?.opus ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.opus,
|
|
127801
|
-
sonnet: overrides?.sonnet ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.sonnet,
|
|
127802
|
-
haiku: overrides?.haiku ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.haiku
|
|
127803
|
-
},
|
|
128060
|
+
models: { fable: tierModel("fable"), opus: tierModel("opus"), sonnet: tierModel("sonnet"), haiku: tierModel("haiku") },
|
|
128061
|
+
aliases,
|
|
127804
128062
|
effort: config2?.effort ?? ANTIGRAVITY_DEFAULT_EFFORT,
|
|
127805
128063
|
cloud: {
|
|
127806
128064
|
endpoint: config2?.cloud?.endpoint,
|
|
@@ -127814,14 +128072,58 @@ function resolveAntigravityConfig(config2) {
|
|
|
127814
128072
|
};
|
|
127815
128073
|
}
|
|
127816
128074
|
var CONTEXT_MARKER_1M = "[1m]";
|
|
128075
|
+
var BACKEND_FAMILY_PREFIXES = ["gemini-", "antigravity-", "gpt-oss-"];
|
|
128076
|
+
var BACKEND_CLAUDE_NAME = /^claude-.+-(?:low|medium|high|thinking)$/;
|
|
128077
|
+
function isBackendModelName(name) {
|
|
128078
|
+
return BACKEND_FAMILY_PREFIXES.some((prefix) => name.startsWith(prefix)) || BACKEND_CLAUDE_NAME.test(name);
|
|
128079
|
+
}
|
|
127817
128080
|
function mapModel2(requested, config2) {
|
|
127818
128081
|
const stripped = requested.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? requested.slice(0, -CONTEXT_MARKER_1M.length) : requested;
|
|
127819
|
-
if (stripped.startsWith("gemini-") || stripped.startsWith("antigravity-")) {
|
|
127820
|
-
return stripped;
|
|
127821
|
-
}
|
|
127822
128082
|
const lower = stripped.toLowerCase();
|
|
128083
|
+
const alias = config2.aliases.get(lower);
|
|
128084
|
+
if (alias !== void 0) {
|
|
128085
|
+
return alias;
|
|
128086
|
+
}
|
|
128087
|
+
if (isBackendModelName(stripped)) {
|
|
128088
|
+
return [stripped];
|
|
128089
|
+
}
|
|
127823
128090
|
const tier = ANTIGRAVITY_TIERS.find((candidate) => lower.includes(candidate));
|
|
127824
|
-
return tier === void 0 ? config2.defaultModel : config2.models[tier];
|
|
128091
|
+
return tier === void 0 ? [config2.defaultModel] : config2.models[tier];
|
|
128092
|
+
}
|
|
128093
|
+
function chooseCandidate(candidates, routing) {
|
|
128094
|
+
const first = candidates[0];
|
|
128095
|
+
if (first === void 0) {
|
|
128096
|
+
throw new Error("A model target holds at least one candidate");
|
|
128097
|
+
}
|
|
128098
|
+
if (routing === void 0 || candidates.length === 1) {
|
|
128099
|
+
return first;
|
|
128100
|
+
}
|
|
128101
|
+
if (routing.previous !== void 0 && candidates.includes(routing.previous) && antigravityQuotaExhaustion(routing.quota, routing.previous, routing.nowMs) === void 0) {
|
|
128102
|
+
return routing.previous;
|
|
128103
|
+
}
|
|
128104
|
+
const unspent = candidates.filter((model) => antigravityQuotaExhaustion(routing.quota, model, routing.nowMs) === void 0);
|
|
128105
|
+
if (unspent[0] === first) {
|
|
128106
|
+
return first;
|
|
128107
|
+
}
|
|
128108
|
+
const neutral = 1;
|
|
128109
|
+
let best;
|
|
128110
|
+
for (const model of unspent) {
|
|
128111
|
+
const pressure = antigravityQuotaPressure(routing.quota, model) ?? neutral;
|
|
128112
|
+
if (best === void 0 || pressure > best.pressure) {
|
|
128113
|
+
best = { model, pressure };
|
|
128114
|
+
}
|
|
128115
|
+
}
|
|
128116
|
+
if (best !== void 0) {
|
|
128117
|
+
return best.model;
|
|
128118
|
+
}
|
|
128119
|
+
let soonest;
|
|
128120
|
+
for (const model of candidates) {
|
|
128121
|
+
const exhaustion = antigravityQuotaExhaustion(routing.quota, model, routing.nowMs);
|
|
128122
|
+
if (exhaustion !== void 0 && (soonest === void 0 || exhaustion.resetSec < soonest.resetSec)) {
|
|
128123
|
+
soonest = { model, resetSec: exhaustion.resetSec };
|
|
128124
|
+
}
|
|
128125
|
+
}
|
|
128126
|
+
return soonest?.model ?? first;
|
|
127825
128127
|
}
|
|
127826
128128
|
var EFFORT_TO_BUDGET = {
|
|
127827
128129
|
none: 0,
|
|
@@ -127886,7 +128188,7 @@ function turnBlocks2(message) {
|
|
|
127886
128188
|
}
|
|
127887
128189
|
return blocks.map((block2) => isTextBlock(block2) ? { ...block2, text: systemReminder2(block2.text) } : block2);
|
|
127888
128190
|
}
|
|
127889
|
-
function
|
|
128191
|
+
function isRecord9(value2) {
|
|
127890
128192
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
127891
128193
|
}
|
|
127892
128194
|
function messagesToGeminiContents(messages, names, toolIdToName) {
|
|
@@ -127932,7 +128234,7 @@ function messagesToGeminiContents(messages, names, toolIdToName) {
|
|
|
127932
128234
|
ensureRole("model").push({
|
|
127933
128235
|
functionCall: {
|
|
127934
128236
|
name: sanitizedName,
|
|
127935
|
-
args:
|
|
128237
|
+
args: isRecord9(block2.input) ? block2.input : {}
|
|
127936
128238
|
},
|
|
127937
128239
|
// The relay remembered the signature the backend attached to this exact call; echoing it back is what the backend requires of a repeated function call. A call with none remembered (made before a door restart, evicted from the bounded store, or produced by another model in a resumed session) gets the backend's documented bypass, since history is resent whole on every request and a single unsigned call would otherwise fail the whole conversation for good.
|
|
127938
128240
|
thoughtSignature: signature ?? UNVERIFIED_THOUGHT_SIGNATURE
|
|
@@ -127954,7 +128256,7 @@ function messagesToGeminiContents(messages, names, toolIdToName) {
|
|
|
127954
128256
|
var EMPTY_SCHEMA = { type: "object", properties: {} };
|
|
127955
128257
|
var GEMINI_SCHEMA_KEYS = /* @__PURE__ */ new Set(["type", "format", "description", "nullable", "enum", "anyOf", "items", "properties", "required", "minimum", "maximum", "minItems", "maxItems"]);
|
|
127956
128258
|
function describeSchemaValue(node2) {
|
|
127957
|
-
if (!
|
|
128259
|
+
if (!isRecord9(node2)) {
|
|
127958
128260
|
return "any value";
|
|
127959
128261
|
}
|
|
127960
128262
|
const type2 = node2.type;
|
|
@@ -127965,7 +128267,7 @@ function describeSchemaValue(node2) {
|
|
|
127965
128267
|
return name === "object" ? "an object" : `a ${name}`;
|
|
127966
128268
|
}
|
|
127967
128269
|
function toGeminiSchema(node2) {
|
|
127968
|
-
if (!
|
|
128270
|
+
if (!isRecord9(node2)) {
|
|
127969
128271
|
return node2;
|
|
127970
128272
|
}
|
|
127971
128273
|
const out = {};
|
|
@@ -127983,7 +128285,7 @@ function toGeminiSchema(node2) {
|
|
|
127983
128285
|
if (!GEMINI_SCHEMA_KEYS.has(key)) {
|
|
127984
128286
|
if (key === "additionalProperties" && value2 !== false) {
|
|
127985
128287
|
notes.push(`Each value is ${describeSchemaValue(value2)}.`);
|
|
127986
|
-
} else if (key === "propertyNames" &&
|
|
128288
|
+
} else if (key === "propertyNames" && isRecord9(value2) && typeof value2.pattern === "string") {
|
|
127987
128289
|
notes.push(`Keys match ${value2.pattern}.`);
|
|
127988
128290
|
}
|
|
127989
128291
|
continue;
|
|
@@ -128000,7 +128302,7 @@ function toGeminiSchema(node2) {
|
|
|
128000
128302
|
const description = typeof out.description === "string" ? out.description : "";
|
|
128001
128303
|
out.description = `${description}${description === "" ? "" : " "}${notes.join(" ")}`;
|
|
128002
128304
|
}
|
|
128003
|
-
if ("properties" in out &&
|
|
128305
|
+
if ("properties" in out && isRecord9(out.properties)) {
|
|
128004
128306
|
out.properties = Object.fromEntries(Object.entries(out.properties).map(([name, child]) => [name, toGeminiSchema(child)]));
|
|
128005
128307
|
}
|
|
128006
128308
|
if ("items" in out) {
|
|
@@ -128022,7 +128324,7 @@ function mapTools2(tools, names) {
|
|
|
128022
128324
|
return {
|
|
128023
128325
|
name: shortToolName2(tool.name, names),
|
|
128024
128326
|
description: tool.description,
|
|
128025
|
-
parameters:
|
|
128327
|
+
parameters: isRecord9(converted) ? converted : EMPTY_SCHEMA
|
|
128026
128328
|
};
|
|
128027
128329
|
});
|
|
128028
128330
|
return [{ functionDeclarations: declarations }];
|
|
@@ -128046,16 +128348,16 @@ function completeEffortSuffix(model, request7, config2) {
|
|
|
128046
128348
|
if (splitEffortSuffix(model) !== void 0) {
|
|
128047
128349
|
return model;
|
|
128048
128350
|
}
|
|
128049
|
-
const configured = [config2.defaultModel, ...Object.values(config2.models)];
|
|
128351
|
+
const configured = [config2.defaultModel, ...Object.values(config2.models).flat(), ...[...config2.aliases.values()].flat()];
|
|
128050
128352
|
const effort = request7.output_config?.effort;
|
|
128051
128353
|
const level = ANTIGRAVITY_EFFORTS.find((candidate) => candidate === effort) ?? config2.effort;
|
|
128052
128354
|
const suffixed = `${model}-${effortSuffixOf(level)}`;
|
|
128053
128355
|
return configured.some((entry) => entry === suffixed || splitEffortSuffix(entry)?.base === model) ? suffixed : model;
|
|
128054
128356
|
}
|
|
128055
|
-
function translateRequest2(request7, config2) {
|
|
128357
|
+
function translateRequest2(request7, config2, routing) {
|
|
128056
128358
|
const toolNames = /* @__PURE__ */ new Map();
|
|
128057
128359
|
const toolIdToName = /* @__PURE__ */ new Map();
|
|
128058
|
-
const model =
|
|
128360
|
+
const model = chooseCandidate(mapModel2(request7.model ?? "", config2).map((candidate) => completeEffortSuffix(candidate, request7, config2)), routing);
|
|
128059
128361
|
const thinkingBudget = mapEffort2(request7, config2);
|
|
128060
128362
|
const systemInstruction = systemToInstruction(request7.system);
|
|
128061
128363
|
const contents = messagesToGeminiContents(request7.messages, toolNames, toolIdToName);
|
|
@@ -128073,223 +128375,6 @@ function translateRequest2(request7, config2) {
|
|
|
128073
128375
|
};
|
|
128074
128376
|
}
|
|
128075
128377
|
|
|
128076
|
-
// src/antigravity/quota.ts
|
|
128077
|
-
init_cloudUpstream();
|
|
128078
|
-
var MS_PER_SECOND8 = 1e3;
|
|
128079
|
-
var DEFAULT_RETRY_AFTER_SECONDS = 60;
|
|
128080
|
-
var FRACTION_DIGITS = 3;
|
|
128081
|
-
var GEMINI_5H_KEYS = ["gemini-5h", "gemini_5h", "gemini"];
|
|
128082
|
-
var GEMINI_WEEKLY_KEYS = ["gemini-weekly", "gemini_weekly"];
|
|
128083
|
-
var ARGON_WEEKLY_KEYS = ["gemini-argon-wtu-weekly"];
|
|
128084
|
-
var THIRD_PARTY_5H_KEYS = ["3p-5h", "claude-5h", "3p_5h", "claude_5h", "claude"];
|
|
128085
|
-
var THIRD_PARTY_WEEKLY_KEYS = ["3p-weekly", "claude-weekly", "3p_weekly", "claude_weekly"];
|
|
128086
|
-
function findBucket(quota, keys) {
|
|
128087
|
-
for (const key of keys) {
|
|
128088
|
-
const bucket = quota[key];
|
|
128089
|
-
if (bucket !== void 0) {
|
|
128090
|
-
return bucket;
|
|
128091
|
-
}
|
|
128092
|
-
}
|
|
128093
|
-
return void 0;
|
|
128094
|
-
}
|
|
128095
|
-
function selectAntigravityBuckets(quota, model) {
|
|
128096
|
-
const lower = (model ?? "").toLowerCase();
|
|
128097
|
-
if (lower.includes("argon")) {
|
|
128098
|
-
return { fiveHour: void 0, weekly: findBucket(quota, ARGON_WEEKLY_KEYS) };
|
|
128099
|
-
}
|
|
128100
|
-
const isGemini = lower.includes("gemini");
|
|
128101
|
-
return {
|
|
128102
|
-
fiveHour: findBucket(quota, isGemini ? GEMINI_5H_KEYS : THIRD_PARTY_5H_KEYS),
|
|
128103
|
-
weekly: findBucket(quota, isGemini ? GEMINI_WEEKLY_KEYS : THIRD_PARTY_WEEKLY_KEYS)
|
|
128104
|
-
};
|
|
128105
|
-
}
|
|
128106
|
-
function calculateUtilization(remainingFraction) {
|
|
128107
|
-
if (remainingFraction === void 0 || !Number.isFinite(remainingFraction)) {
|
|
128108
|
-
return void 0;
|
|
128109
|
-
}
|
|
128110
|
-
const clampedRem = Math.max(0, Math.min(1, remainingFraction));
|
|
128111
|
-
const used = Math.max(0, 1 - clampedRem);
|
|
128112
|
-
return used.toFixed(FRACTION_DIGITS);
|
|
128113
|
-
}
|
|
128114
|
-
function calculateResetTimestamp(nowSec, resetInSeconds) {
|
|
128115
|
-
if (resetInSeconds === void 0 || !Number.isFinite(resetInSeconds) || resetInSeconds < 0) {
|
|
128116
|
-
return void 0;
|
|
128117
|
-
}
|
|
128118
|
-
return String(nowSec + Math.ceil(resetInSeconds));
|
|
128119
|
-
}
|
|
128120
|
-
function parseRetryAfterSeconds(raw, defaultSeconds = DEFAULT_RETRY_AFTER_SECONDS) {
|
|
128121
|
-
if (raw === null || raw === void 0 || raw.trim() === "") {
|
|
128122
|
-
return defaultSeconds;
|
|
128123
|
-
}
|
|
128124
|
-
const numeric = Number(raw);
|
|
128125
|
-
if (Number.isFinite(numeric) && numeric > 0) {
|
|
128126
|
-
return Math.ceil(numeric);
|
|
128127
|
-
}
|
|
128128
|
-
const parsedDate = Date.parse(raw);
|
|
128129
|
-
if (!Number.isNaN(parsedDate)) {
|
|
128130
|
-
const diffSec = Math.ceil((parsedDate - Date.now()) / MS_PER_SECOND8);
|
|
128131
|
-
return Math.max(1, diffSec);
|
|
128132
|
-
}
|
|
128133
|
-
return defaultSeconds;
|
|
128134
|
-
}
|
|
128135
|
-
function unifiedAntigravityQuotaHeaders(params) {
|
|
128136
|
-
const rejected = params.rejected === true;
|
|
128137
|
-
const nowSec = Math.floor(params.nowMs / MS_PER_SECOND8);
|
|
128138
|
-
const { fiveHour: b5h, weekly: bWk } = selectAntigravityBuckets(params.quota ?? {}, params.model);
|
|
128139
|
-
const used5h = calculateUtilization(b5h?.remaining_fraction);
|
|
128140
|
-
const reset5h = calculateResetTimestamp(nowSec, b5h?.reset_in_seconds);
|
|
128141
|
-
const used7d = calculateUtilization(bWk?.remaining_fraction);
|
|
128142
|
-
const reset7d = calculateResetTimestamp(nowSec, bWk?.reset_in_seconds);
|
|
128143
|
-
const exhaustion = rejected ? antigravityQuotaExhaustion(params.quota, params.model, params.nowMs) : void 0;
|
|
128144
|
-
if (rejected && exhaustion === void 0) {
|
|
128145
|
-
return {};
|
|
128146
|
-
}
|
|
128147
|
-
if (!rejected && used5h === void 0 && reset5h === void 0 && used7d === void 0 && reset7d === void 0) {
|
|
128148
|
-
return {};
|
|
128149
|
-
}
|
|
128150
|
-
const headers = {
|
|
128151
|
-
"anthropic-ratelimit-unified-status": rejected ? "rejected" : "allowed"
|
|
128152
|
-
};
|
|
128153
|
-
let earliestResetSec;
|
|
128154
|
-
if (used5h !== void 0 && reset5h !== void 0) {
|
|
128155
|
-
headers["anthropic-ratelimit-unified-5h-utilization"] = used5h;
|
|
128156
|
-
headers["anthropic-ratelimit-unified-5h-reset"] = reset5h;
|
|
128157
|
-
earliestResetSec = Number(reset5h);
|
|
128158
|
-
if (rejected) {
|
|
128159
|
-
headers["anthropic-ratelimit-unified-5h-status"] = exhaustion?.exhaustedWindows.includes("five_hour") === true ? "rejected" : "allowed";
|
|
128160
|
-
}
|
|
128161
|
-
}
|
|
128162
|
-
if (used7d !== void 0 && reset7d !== void 0) {
|
|
128163
|
-
headers["anthropic-ratelimit-unified-7d-utilization"] = used7d;
|
|
128164
|
-
headers["anthropic-ratelimit-unified-7d-reset"] = reset7d;
|
|
128165
|
-
const reset7dSec = Number(reset7d);
|
|
128166
|
-
earliestResetSec = earliestResetSec === void 0 ? reset7dSec : Math.min(earliestResetSec, reset7dSec);
|
|
128167
|
-
if (rejected) {
|
|
128168
|
-
headers["anthropic-ratelimit-unified-7d-status"] = exhaustion?.exhaustedWindows.includes("seven_day") === true ? "rejected" : "allowed";
|
|
128169
|
-
}
|
|
128170
|
-
}
|
|
128171
|
-
if (exhaustion !== void 0) {
|
|
128172
|
-
headers["anthropic-ratelimit-unified-representative-claim"] = exhaustion.window;
|
|
128173
|
-
headers["anthropic-ratelimit-unified-reset"] = String(exhaustion.resetSec);
|
|
128174
|
-
headers["retry-after"] = String(Math.max(1, exhaustion.resetSec - nowSec));
|
|
128175
|
-
headers["x-should-retry"] = "false";
|
|
128176
|
-
return headers;
|
|
128177
|
-
}
|
|
128178
|
-
if (earliestResetSec !== void 0) {
|
|
128179
|
-
headers["anthropic-ratelimit-unified-reset"] = String(earliestResetSec);
|
|
128180
|
-
}
|
|
128181
|
-
return headers;
|
|
128182
|
-
}
|
|
128183
|
-
function antigravityQuotaExhaustion(quota, model, nowMs) {
|
|
128184
|
-
const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
|
|
128185
|
-
const nowSec = Math.floor(nowMs / MS_PER_SECOND8);
|
|
128186
|
-
const spent = [];
|
|
128187
|
-
for (const [window, bucket] of [["five_hour", fiveHour], ["seven_day", weekly]]) {
|
|
128188
|
-
const remaining = bucket?.remaining_fraction;
|
|
128189
|
-
const resetIn = bucket?.reset_in_seconds;
|
|
128190
|
-
if (remaining !== void 0 && Number.isFinite(remaining) && remaining <= 0 && resetIn !== void 0 && Number.isFinite(resetIn) && resetIn >= 0) {
|
|
128191
|
-
spent.push({ window, resetSec: nowSec + Math.ceil(resetIn) });
|
|
128192
|
-
}
|
|
128193
|
-
}
|
|
128194
|
-
const binding = spent.reduce((latest, next) => latest === void 0 || next.resetSec > latest.resetSec ? next : latest, void 0);
|
|
128195
|
-
return binding === void 0 ? void 0 : { window: binding.window, resetSec: binding.resetSec, exhaustedWindows: spent.map((entry) => entry.window) };
|
|
128196
|
-
}
|
|
128197
|
-
function isRecord9(value2) {
|
|
128198
|
-
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
128199
|
-
}
|
|
128200
|
-
function bucketToEntry(bucket, nowMs) {
|
|
128201
|
-
if (!isRecord9(bucket) || typeof bucket.bucketId !== "string") {
|
|
128202
|
-
return void 0;
|
|
128203
|
-
}
|
|
128204
|
-
const remainingFraction = typeof bucket.remainingFraction === "number" && Number.isFinite(bucket.remainingFraction) ? bucket.remainingFraction : void 0;
|
|
128205
|
-
const resetMs = typeof bucket.resetTime === "string" ? Date.parse(bucket.resetTime) : Number.NaN;
|
|
128206
|
-
const resetInSeconds = Number.isNaN(resetMs) ? void 0 : Math.max(0, Math.ceil((resetMs - nowMs) / MS_PER_SECOND8));
|
|
128207
|
-
if (remainingFraction === void 0 && resetInSeconds === void 0) {
|
|
128208
|
-
return void 0;
|
|
128209
|
-
}
|
|
128210
|
-
return {
|
|
128211
|
-
key: bucket.bucketId,
|
|
128212
|
-
entry: {
|
|
128213
|
-
...remainingFraction === void 0 ? {} : { remaining_fraction: remainingFraction },
|
|
128214
|
-
...resetInSeconds === void 0 ? {} : { reset_in_seconds: resetInSeconds }
|
|
128215
|
-
}
|
|
128216
|
-
};
|
|
128217
|
-
}
|
|
128218
|
-
async function fetchAntigravityQuotaSummary(params) {
|
|
128219
|
-
const fetchFn = params.fetchFn ?? fetch;
|
|
128220
|
-
let response;
|
|
128221
|
-
try {
|
|
128222
|
-
response = await fetchFn(`${params.endpoint ?? CCPA_ENDPOINT}/v1internal:retrieveUserQuotaSummary`, {
|
|
128223
|
-
method: "POST",
|
|
128224
|
-
headers: {
|
|
128225
|
-
"Content-Type": "application/json",
|
|
128226
|
-
Authorization: `Bearer ${params.token}`,
|
|
128227
|
-
"User-Agent": CCPA_USER_AGENT
|
|
128228
|
-
},
|
|
128229
|
-
body: JSON.stringify({ project: params.projectId ?? CCPA_DEFAULT_PROJECT_ID })
|
|
128230
|
-
});
|
|
128231
|
-
} catch {
|
|
128232
|
-
return void 0;
|
|
128233
|
-
}
|
|
128234
|
-
if (!response.ok) {
|
|
128235
|
-
return void 0;
|
|
128236
|
-
}
|
|
128237
|
-
let parsed;
|
|
128238
|
-
try {
|
|
128239
|
-
parsed = await response.json();
|
|
128240
|
-
} catch {
|
|
128241
|
-
return void 0;
|
|
128242
|
-
}
|
|
128243
|
-
if (!isRecord9(parsed) || !Array.isArray(parsed.groups)) {
|
|
128244
|
-
return void 0;
|
|
128245
|
-
}
|
|
128246
|
-
const map2 = {};
|
|
128247
|
-
for (const group of parsed.groups) {
|
|
128248
|
-
if (!isRecord9(group) || !Array.isArray(group.buckets)) {
|
|
128249
|
-
continue;
|
|
128250
|
-
}
|
|
128251
|
-
for (const bucket of group.buckets) {
|
|
128252
|
-
const read = bucketToEntry(bucket, params.nowMs);
|
|
128253
|
-
if (read !== void 0) {
|
|
128254
|
-
map2[read.key] = read.entry;
|
|
128255
|
-
}
|
|
128256
|
-
}
|
|
128257
|
-
}
|
|
128258
|
-
return Object.keys(map2).length > 0 ? map2 : void 0;
|
|
128259
|
-
}
|
|
128260
|
-
var ANTIGRAVITY_QUOTA_REFRESH_MS = 6e4;
|
|
128261
|
-
function createCachedAntigravityQuotaSource(params) {
|
|
128262
|
-
let cachedAt = Number.NEGATIVE_INFINITY;
|
|
128263
|
-
let cached2;
|
|
128264
|
-
let readAtMs = Number.NEGATIVE_INFINITY;
|
|
128265
|
-
let refresh;
|
|
128266
|
-
const refreshMs = params.refreshMs ?? ANTIGRAVITY_QUOTA_REFRESH_MS;
|
|
128267
|
-
const run = async () => {
|
|
128268
|
-
const nowMs = params.now();
|
|
128269
|
-
const read = await params.fetchSummary(nowMs);
|
|
128270
|
-
if (read !== void 0) {
|
|
128271
|
-
cached2 = read;
|
|
128272
|
-
readAtMs = nowMs;
|
|
128273
|
-
}
|
|
128274
|
-
cachedAt = params.now();
|
|
128275
|
-
};
|
|
128276
|
-
return () => {
|
|
128277
|
-
const nowMs = params.now();
|
|
128278
|
-
if (nowMs - cachedAt >= refreshMs) {
|
|
128279
|
-
refresh ??= run().finally(() => {
|
|
128280
|
-
refresh = void 0;
|
|
128281
|
-
});
|
|
128282
|
-
}
|
|
128283
|
-
return cached2 === void 0 ? void 0 : ageQuotaMap(cached2, nowMs - readAtMs);
|
|
128284
|
-
};
|
|
128285
|
-
}
|
|
128286
|
-
function ageQuotaMap(quota, elapsedMs) {
|
|
128287
|
-
const elapsedSec = elapsedMs / MS_PER_SECOND8;
|
|
128288
|
-
return Object.fromEntries(
|
|
128289
|
-
Object.entries(quota).map(([key, bucket]) => [key, bucket?.reset_in_seconds === void 0 ? bucket : { ...bucket, reset_in_seconds: Math.max(0, bucket.reset_in_seconds - elapsedSec) }])
|
|
128290
|
-
);
|
|
128291
|
-
}
|
|
128292
|
-
|
|
128293
128378
|
// src/frontdoor/providerRoute.ts
|
|
128294
128379
|
init_credential();
|
|
128295
128380
|
init_providersStore();
|
|
@@ -129246,12 +129331,14 @@ async function* callLocalAntigravity(params) {
|
|
|
129246
129331
|
|
|
129247
129332
|
// src/antigravity/route.ts
|
|
129248
129333
|
var MS_PER_SECOND10 = 1e3;
|
|
129334
|
+
var ROUTING_MEMORY_SESSIONS = 256;
|
|
129249
129335
|
function exhaustedMessage(exhaustion) {
|
|
129250
129336
|
const window = exhaustion.window === "five_hour" ? "5-hour" : "weekly";
|
|
129251
129337
|
return `Antigravity ${window} limit reached; it resets at ${new Date(exhaustion.resetSec * MS_PER_SECOND10).toISOString()}.`;
|
|
129252
129338
|
}
|
|
129253
129339
|
function createAntigravityRoute(ports) {
|
|
129254
129340
|
const fallbackId = ports.fallbackId ?? (() => (0, import_node_crypto22.randomUUID)());
|
|
129341
|
+
const lastRouted = /* @__PURE__ */ new Map();
|
|
129255
129342
|
return async (request7) => {
|
|
129256
129343
|
await Promise.resolve();
|
|
129257
129344
|
if (request7.method !== "POST") {
|
|
@@ -129303,13 +129390,24 @@ function createAntigravityRoute(ports) {
|
|
|
129303
129390
|
}
|
|
129304
129391
|
const { config: config2, token, credentialTarget } = lookup;
|
|
129305
129392
|
const requestedModel = parsed.data.model ?? config2.defaultModel;
|
|
129306
|
-
const
|
|
129393
|
+
const nowMs = ports.now?.() ?? Date.now();
|
|
129394
|
+
const sessionKey = parsed.data.metadata?.user_id === void 0 ? void 0 : `${parsed.data.metadata.user_id}\0${parsed.data.model ?? ""}`;
|
|
129395
|
+
const translated = translateRequest2(parsed.data, config2, { quota: ports.quotaSource?.(), nowMs, previous: sessionKey === void 0 ? void 0 : lastRouted.get(sessionKey) });
|
|
129396
|
+
if (sessionKey !== void 0) {
|
|
129397
|
+
lastRouted.delete(sessionKey);
|
|
129398
|
+
lastRouted.set(sessionKey, translated.model);
|
|
129399
|
+
if (lastRouted.size > ROUTING_MEMORY_SESSIONS) {
|
|
129400
|
+
const oldest = lastRouted.keys().next();
|
|
129401
|
+
if (oldest.done !== true) {
|
|
129402
|
+
lastRouted.delete(oldest.value);
|
|
129403
|
+
}
|
|
129404
|
+
}
|
|
129405
|
+
}
|
|
129307
129406
|
const relay = createAntigravityRelay({
|
|
129308
129407
|
requestedModel,
|
|
129309
129408
|
toolNames: translated.toolNames,
|
|
129310
129409
|
fallbackId
|
|
129311
129410
|
});
|
|
129312
|
-
const nowMs = ports.now?.() ?? Date.now();
|
|
129313
129411
|
const upstreamChunks2 = config2.mode === "local" ? callLocalAntigravity({
|
|
129314
129412
|
config: config2,
|
|
129315
129413
|
model: translated.model,
|
|
@@ -133473,13 +133571,12 @@ function payloadWindowsOf(payload) {
|
|
|
133473
133571
|
const seven = isObject4(rateLimits) ? payloadWindow(rateLimits, "seven_day") : void 0;
|
|
133474
133572
|
return { fiveHourUsed: five?.used, fiveHourResetAt: five?.resetAt, sevenDayUsed: seven?.used, sevenDayResetAt: seven?.resetAt };
|
|
133475
133573
|
}
|
|
133476
|
-
function
|
|
133574
|
+
function antigravityQuotaMapOf(payload) {
|
|
133477
133575
|
const quota = isObject4(payload) ? payload.quota : void 0;
|
|
133478
133576
|
if (!isObject4(quota)) {
|
|
133479
|
-
return
|
|
133577
|
+
return void 0;
|
|
133480
133578
|
}
|
|
133481
|
-
|
|
133482
|
-
const buckets = Object.fromEntries(
|
|
133579
|
+
return Object.fromEntries(
|
|
133483
133580
|
Object.entries(quota).flatMap(([key, bucket]) => {
|
|
133484
133581
|
if (!isObject4(bucket)) {
|
|
133485
133582
|
return [];
|
|
@@ -133489,15 +133586,30 @@ function antigravityWindowsOf(payload, nowMs) {
|
|
|
133489
133586
|
return [[key, { ...typeof remaining === "number" ? { remaining_fraction: remaining } : {}, ...typeof resetIn === "number" ? { reset_in_seconds: resetIn } : {} }]];
|
|
133490
133587
|
})
|
|
133491
133588
|
);
|
|
133492
|
-
|
|
133493
|
-
|
|
133589
|
+
}
|
|
133590
|
+
function bucketView(bucket, nowMs) {
|
|
133591
|
+
return {
|
|
133494
133592
|
used: bucket?.remaining_fraction === void 0 || !Number.isFinite(bucket.remaining_fraction) ? void 0 : (1 - Math.min(1, Math.max(0, bucket.remaining_fraction))) * FULL_PERCENT,
|
|
133495
133593
|
resetAt: bucket?.reset_in_seconds === void 0 || !Number.isFinite(bucket.reset_in_seconds) ? void 0 : new Date(nowMs + bucket.reset_in_seconds * MS_PER_SECOND14).toISOString()
|
|
133496
|
-
}
|
|
133497
|
-
|
|
133498
|
-
|
|
133594
|
+
};
|
|
133595
|
+
}
|
|
133596
|
+
function antigravityWindowsOf(payload, nowMs) {
|
|
133597
|
+
const buckets = antigravityQuotaMapOf(payload);
|
|
133598
|
+
if (buckets === void 0) {
|
|
133599
|
+
return { fiveHourUsed: void 0, fiveHourResetAt: void 0, sevenDayUsed: void 0, sevenDayResetAt: void 0 };
|
|
133600
|
+
}
|
|
133601
|
+
const model = isObject4(payload) && isObject4(payload.model) && typeof payload.model.id === "string" ? payload.model.id : void 0;
|
|
133602
|
+
const { fiveHour, weekly } = selectAntigravityBuckets(buckets, model);
|
|
133603
|
+
const five = bucketView(fiveHour, nowMs);
|
|
133604
|
+
const seven = bucketView(weekly, nowMs);
|
|
133499
133605
|
return { fiveHourUsed: five.used, fiveHourResetAt: five.resetAt, sevenDayUsed: seven.used, sevenDayResetAt: seven.resetAt };
|
|
133500
133606
|
}
|
|
133607
|
+
function quotaFamiliesOf(buckets, nowMs) {
|
|
133608
|
+
return antigravityFamilyBuckets(buckets).flatMap(({ label, bucket }) => {
|
|
133609
|
+
const { used, resetAt } = bucketView(bucket, nowMs);
|
|
133610
|
+
return used === void 0 ? [] : [{ measures: label, utilization: used / FULL_PERCENT, resetsAt: resetAt }];
|
|
133611
|
+
});
|
|
133612
|
+
}
|
|
133501
133613
|
function enrichStatuslinePayload(params) {
|
|
133502
133614
|
const identity = identityOf(params.env);
|
|
133503
133615
|
const clientEmail = isObject4(params.payload) && typeof params.payload.email === "string" && params.payload.email !== "" ? params.payload.email : void 0;
|
|
@@ -133520,6 +133632,7 @@ function enrichStatuslinePayload(params) {
|
|
|
133520
133632
|
sevenDayUsed: void 0,
|
|
133521
133633
|
sevenDayResetAt: void 0,
|
|
133522
133634
|
providerQuotaWindows: [],
|
|
133635
|
+
quotaFamilies: [],
|
|
133523
133636
|
headroom: params.headroom
|
|
133524
133637
|
};
|
|
133525
133638
|
if (params.snapshot !== void 0) {
|
|
@@ -133545,9 +133658,22 @@ function enrichStatuslinePayload(params) {
|
|
|
133545
133658
|
}
|
|
133546
133659
|
}
|
|
133547
133660
|
const providerQuotaWindows = [...scopedState?.quota?.windows ?? []].sort((a10, b) => (a10.periodMs ?? Number.POSITIVE_INFINITY) - (b.periodMs ?? Number.POSITIVE_INFINITY)).map((window) => ({ measures: window.measures, utilization: window.utilization, resetsAt: window.resetsAt }));
|
|
133548
|
-
|
|
133661
|
+
const providerBuckets = Object.fromEntries(
|
|
133662
|
+
(scopedState?.quota?.windows ?? []).map((window) => [
|
|
133663
|
+
window.measures,
|
|
133664
|
+
{
|
|
133665
|
+
remaining_fraction: 1 - window.utilization,
|
|
133666
|
+
...window.resetsAt === void 0 ? {} : { reset_in_seconds: (Date.parse(window.resetsAt) - params.nowMs) / MS_PER_SECOND14 }
|
|
133667
|
+
}
|
|
133668
|
+
])
|
|
133669
|
+
);
|
|
133670
|
+
summary = { ...summary, ...windowsOf(states), providerAccountEmail: email3, providerAccountSub: sub, providerPlan: plan, providerQuotaWindows, quotaFamilies: quotaFamiliesOf(providerBuckets, params.nowMs) };
|
|
133549
133671
|
}
|
|
133550
133672
|
if (summary.provider === void 0) {
|
|
133673
|
+
const agyBuckets = antigravityQuotaMapOf(params.payload);
|
|
133674
|
+
if (agyBuckets !== void 0) {
|
|
133675
|
+
summary = { ...summary, quotaFamilies: quotaFamiliesOf(agyBuckets, params.nowMs) };
|
|
133676
|
+
}
|
|
133551
133677
|
for (const own2 of [antigravityWindowsOf(params.payload, params.nowMs), payloadWindowsOf(params.payload)]) {
|
|
133552
133678
|
summary = {
|
|
133553
133679
|
...summary,
|
|
@@ -133891,22 +134017,26 @@ function renderStatuslineBlock(summary, view, terminalWidth, nowMs) {
|
|
|
133891
134017
|
contextGroup.push(new Segment("bar", "", `Ctx ${tokens}`, ` ${percent2}${cache}`, fraction, true));
|
|
133892
134018
|
}
|
|
133893
134019
|
const quotaGroup = [];
|
|
133894
|
-
|
|
133895
|
-
const
|
|
133896
|
-
const color = statusColor(
|
|
133897
|
-
quotaGroup.push(new Segment("bar", "",
|
|
133898
|
-
}
|
|
133899
|
-
if (summary.
|
|
133900
|
-
const
|
|
133901
|
-
|
|
133902
|
-
|
|
133903
|
-
}
|
|
133904
|
-
|
|
133905
|
-
|
|
133906
|
-
|
|
133907
|
-
|
|
133908
|
-
|
|
133909
|
-
|
|
134020
|
+
const drawWindow = (label, fraction, resetsAt) => {
|
|
134021
|
+
const clamped = Math.max(0, Math.min(1, fraction));
|
|
134022
|
+
const color = statusColor(clamped, true);
|
|
134023
|
+
quotaGroup.push(new Segment("bar", "", `${label} `, ` ${color}${(fraction * FULL_PERCENT2).toFixed(1)}%${RESET} (${formatDuration(secondsUntil(resetsAt, nowMs))})`, clamped, true));
|
|
134024
|
+
};
|
|
134025
|
+
if (summary.quotaFamilies.length > 0) {
|
|
134026
|
+
for (const window of summary.quotaFamilies) {
|
|
134027
|
+
drawWindow(window.measures, window.utilization, window.resetsAt);
|
|
134028
|
+
}
|
|
134029
|
+
} else {
|
|
134030
|
+
if (summary.fiveHourUsed !== void 0) {
|
|
134031
|
+
drawWindow("5h", summary.fiveHourUsed / FULL_PERCENT2, summary.fiveHourResetAt);
|
|
134032
|
+
}
|
|
134033
|
+
if (summary.sevenDayUsed !== void 0) {
|
|
134034
|
+
drawWindow("Wk", summary.sevenDayUsed / FULL_PERCENT2, summary.sevenDayResetAt);
|
|
134035
|
+
}
|
|
134036
|
+
if (summary.fiveHourUsed === void 0 && summary.sevenDayUsed === void 0) {
|
|
134037
|
+
for (const window of summary.providerQuotaWindows) {
|
|
134038
|
+
drawWindow(window.measures, window.utilization, window.resetsAt);
|
|
134039
|
+
}
|
|
133910
134040
|
}
|
|
133911
134041
|
}
|
|
133912
134042
|
const width = Math.max(TWENTY, terminalWidth - RESERVED_COLUMNS);
|
|
@@ -145013,7 +145143,7 @@ function antigravityConfigFromOptions(options) {
|
|
|
145013
145143
|
const candidate = {
|
|
145014
145144
|
...options.antigravityMode === void 0 ? {} : { mode: options.antigravityMode },
|
|
145015
145145
|
...options.antigravityDefaultModel === void 0 ? {} : { defaultModel: options.antigravityDefaultModel },
|
|
145016
|
-
...options.antigravityModel === void 0 ? {} : { models: options.antigravityModel },
|
|
145146
|
+
...options.antigravityModel === void 0 ? {} : { models: Object.fromEntries(Object.entries(options.antigravityModel).map(([name, target]) => [name, target.includes(",") ? target.split(",") : target])) },
|
|
145017
145147
|
...options.antigravityEffort === void 0 ? {} : { effort: options.antigravityEffort },
|
|
145018
145148
|
...cloud === void 0 ? {} : { cloud },
|
|
145019
145149
|
...local === void 0 ? {} : { local }
|
|
@@ -145055,7 +145185,7 @@ function registerProviderCommand(program2, deps) {
|
|
|
145055
145185
|
new Option("--credential-target <target>", "Where the token goes: bearer sets ANTHROPIC_AUTH_TOKEN (default), apiKey sets ANTHROPIC_API_KEY.").choices(
|
|
145056
145186
|
PROVIDER_CREDENTIAL_TARGETS
|
|
145057
145187
|
)
|
|
145058
|
-
).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).addOption(new Option("--codex-login <login>", "Codex providers: which login the upstream call uses, the Codex CLI's own login or a Sign in with ChatGPT grant from `agent-shim codex login`.").choices(CODEX_LOGINS)).addOption(new Option("--antigravity-mode <mode>", "Antigravity providers: cloud (direct Gemini/Vertex) or local (ACP daemon).").choices(ANTIGRAVITY_MODES)).option("--antigravity-default-model <model>", "Antigravity providers: the model a request maps to when no tier matches.").option("--antigravity-model <tier=model>", "Antigravity providers: the model
|
|
145188
|
+
).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).addOption(new Option("--codex-login <login>", "Codex providers: which login the upstream call uses, the Codex CLI's own login or a Sign in with ChatGPT grant from `agent-shim codex login`.").choices(CODEX_LOGINS)).addOption(new Option("--antigravity-mode <mode>", "Antigravity providers: cloud (direct Gemini/Vertex) or local (ACP daemon).").choices(ANTIGRAVITY_MODES)).option("--antigravity-default-model <model>", "Antigravity providers: the model a request maps to when no tier matches.").option("--antigravity-model <tier=model>", "Antigravity providers: the model a tier (fable, opus, sonnet or haiku, matched by substring) or an alias (any other name, matched whole, selectable with /model) maps to; a comma-separated list routes by available quota, first unspent first (repeatable).", collectStringPair).addOption(new Option("--antigravity-effort <effort>", "Antigravity providers: reasoning effort.").choices(ANTIGRAVITY_EFFORTS)).option("--antigravity-endpoint <url>", "Antigravity cloud providers: custom API endpoint URL.").option("--antigravity-project-id <id>", "Antigravity cloud providers: Google Cloud project ID (for Vertex AI).").option("--antigravity-location <loc>", "Antigravity cloud providers: Google Cloud location (for Vertex AI).").option("--antigravity-command <cmd...>", "Antigravity local providers: command to spawn ACP server.", collectRepeated).option("--antigravity-socket <path>", "Antigravity local providers: path to existing Unix domain socket.").option("--json", "Print the result as JSON.").action((name, options) => {
|
|
145059
145189
|
const codex = codexConfigFromOptions(options);
|
|
145060
145190
|
const antigravity = antigravityConfigFromOptions(options);
|
|
145061
145191
|
const created = addProvider(paths, name, {
|
|
@@ -145166,7 +145296,10 @@ function registerProviderCommand(program2, deps) {
|
|
|
145166
145296
|
} else if (isAntigravityProvider(found)) {
|
|
145167
145297
|
const config2 = resolveAntigravityConfig(found.antigravity);
|
|
145168
145298
|
console.log(`Antigravity mode: ${config2.mode}`);
|
|
145169
|
-
console.log(`Antigravity models: ${ANTIGRAVITY_TIERS.map((tier) => `${tier}=${config2.models[tier]}`).join(", ")}, otherwise ${config2.defaultModel}`);
|
|
145299
|
+
console.log(`Antigravity models: ${ANTIGRAVITY_TIERS.map((tier) => `${tier}=${config2.models[tier].join(" > ")}`).join(", ")}, otherwise ${config2.defaultModel}`);
|
|
145300
|
+
if (config2.aliases.size > 0) {
|
|
145301
|
+
console.log(`Antigravity aliases: ${[...config2.aliases].map(([alias, model]) => `${alias}=${model.join(" > ")}`).join(", ")}`);
|
|
145302
|
+
}
|
|
145170
145303
|
console.log(`Antigravity effort: ${config2.effort}`);
|
|
145171
145304
|
console.log(`Endpoint: ${describeProviderEndpoint(found)}`);
|
|
145172
145305
|
} else {
|
package/dist/index.cjs
CHANGED
|
@@ -242,7 +242,7 @@ function isTimeZone(name) {
|
|
|
242
242
|
return false;
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
|
-
var import_node_path2, import_zod, import_trilean, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
245
|
+
var import_node_path2, import_zod, import_trilean, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
246
246
|
var init_schema = __esm({
|
|
247
247
|
"src/config/schema.ts"() {
|
|
248
248
|
"use strict";
|
|
@@ -346,23 +346,19 @@ var init_schema = __esm({
|
|
|
346
346
|
ANTIGRAVITY_EFFORTS = ["none", "low", "medium", "high", "xhigh", "max"];
|
|
347
347
|
ANTIGRAVITY_DEFAULT_MODE = "cloud";
|
|
348
348
|
ANTIGRAVITY_DEFAULT_TIER_MODELS = Object.freeze({
|
|
349
|
-
fable: "gemini-3.8-flash-high",
|
|
350
|
-
opus: "gemini-3.8-flash-high",
|
|
351
|
-
sonnet: "gemini-3.8-flash-medium",
|
|
352
|
-
haiku: "gemini-3.8-flash-low"
|
|
349
|
+
fable: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
|
|
350
|
+
opus: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
|
|
351
|
+
sonnet: ["claude-sonnet-5-5-medium", "gemini-4-argon-medium", "gemini-3.8-flash-medium"],
|
|
352
|
+
haiku: ["gemini-3.8-flash-low", "gemini-4-argon-low", "gpt-oss-120b-medium"]
|
|
353
353
|
});
|
|
354
|
+
AntigravityModelTargetSchema = import_zod.z.union([import_zod.z.string().min(1), import_zod.z.array(import_zod.z.string().min(1)).min(1)]);
|
|
354
355
|
AntigravityProviderConfigSchema = import_zod.z.strictObject({
|
|
355
356
|
/** Operational mode: direct cloud endpoint or local ACP daemon. Defaults to `cloud`. */
|
|
356
357
|
mode: import_zod.z.enum(ANTIGRAVITY_MODES).optional(),
|
|
357
358
|
/** The model a request maps to when no tier matches its model name. */
|
|
358
359
|
defaultModel: import_zod.z.string().min(1).optional(),
|
|
359
|
-
/**
|
|
360
|
-
models: import_zod.z.
|
|
361
|
-
fable: import_zod.z.string().min(1).optional(),
|
|
362
|
-
opus: import_zod.z.string().min(1).optional(),
|
|
363
|
-
sonnet: import_zod.z.string().min(1).optional(),
|
|
364
|
-
haiku: import_zod.z.string().min(1).optional()
|
|
365
|
-
}).optional(),
|
|
360
|
+
/** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
|
|
361
|
+
models: import_zod.z.record(import_zod.z.string().min(1), AntigravityModelTargetSchema).optional(),
|
|
366
362
|
/** The reasoning effort used when the request's own effort is not one the backend accepts. */
|
|
367
363
|
effort: import_zod.z.enum(ANTIGRAVITY_EFFORTS).optional(),
|
|
368
364
|
/** Cloud-specific settings (for `mode: "cloud"`). */
|
|
@@ -2841,7 +2837,7 @@ var init_package = __esm({
|
|
|
2841
2837
|
"package.json"() {
|
|
2842
2838
|
package_default = {
|
|
2843
2839
|
name: "claude-use",
|
|
2844
|
-
version: "11.
|
|
2840
|
+
version: "11.17.0",
|
|
2845
2841
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
2846
2842
|
license: "MIT",
|
|
2847
2843
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
package/dist/index.mjs
CHANGED
|
@@ -223,7 +223,7 @@ function isTimeZone(name) {
|
|
|
223
223
|
return false;
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
-
var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
226
|
+
var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
227
227
|
var init_schema = __esm({
|
|
228
228
|
"src/config/schema.ts"() {
|
|
229
229
|
"use strict";
|
|
@@ -324,23 +324,19 @@ var init_schema = __esm({
|
|
|
324
324
|
ANTIGRAVITY_EFFORTS = ["none", "low", "medium", "high", "xhigh", "max"];
|
|
325
325
|
ANTIGRAVITY_DEFAULT_MODE = "cloud";
|
|
326
326
|
ANTIGRAVITY_DEFAULT_TIER_MODELS = Object.freeze({
|
|
327
|
-
fable: "gemini-3.8-flash-high",
|
|
328
|
-
opus: "gemini-3.8-flash-high",
|
|
329
|
-
sonnet: "gemini-3.8-flash-medium",
|
|
330
|
-
haiku: "gemini-3.8-flash-low"
|
|
327
|
+
fable: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
|
|
328
|
+
opus: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
|
|
329
|
+
sonnet: ["claude-sonnet-5-5-medium", "gemini-4-argon-medium", "gemini-3.8-flash-medium"],
|
|
330
|
+
haiku: ["gemini-3.8-flash-low", "gemini-4-argon-low", "gpt-oss-120b-medium"]
|
|
331
331
|
});
|
|
332
|
+
AntigravityModelTargetSchema = z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]);
|
|
332
333
|
AntigravityProviderConfigSchema = z.strictObject({
|
|
333
334
|
/** Operational mode: direct cloud endpoint or local ACP daemon. Defaults to `cloud`. */
|
|
334
335
|
mode: z.enum(ANTIGRAVITY_MODES).optional(),
|
|
335
336
|
/** The model a request maps to when no tier matches its model name. */
|
|
336
337
|
defaultModel: z.string().min(1).optional(),
|
|
337
|
-
/**
|
|
338
|
-
models: z.
|
|
339
|
-
fable: z.string().min(1).optional(),
|
|
340
|
-
opus: z.string().min(1).optional(),
|
|
341
|
-
sonnet: z.string().min(1).optional(),
|
|
342
|
-
haiku: z.string().min(1).optional()
|
|
343
|
-
}).optional(),
|
|
338
|
+
/** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
|
|
339
|
+
models: z.record(z.string().min(1), AntigravityModelTargetSchema).optional(),
|
|
344
340
|
/** The reasoning effort used when the request's own effort is not one the backend accepts. */
|
|
345
341
|
effort: z.enum(ANTIGRAVITY_EFFORTS).optional(),
|
|
346
342
|
/** Cloud-specific settings (for `mode: "cloud"`). */
|
|
@@ -2817,7 +2813,7 @@ var init_package = __esm({
|
|
|
2817
2813
|
"package.json"() {
|
|
2818
2814
|
package_default = {
|
|
2819
2815
|
name: "claude-use",
|
|
2820
|
-
version: "11.
|
|
2816
|
+
version: "11.17.0",
|
|
2821
2817
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
2822
2818
|
license: "MIT",
|
|
2823
2819
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
package/dist/types/index.d.ts
CHANGED
|
@@ -390,12 +390,7 @@ declare const AntigravityProviderConfigSchema: z.ZodObject<{
|
|
|
390
390
|
local: "local";
|
|
391
391
|
}>>;
|
|
392
392
|
defaultModel: z.ZodOptional<z.ZodString>;
|
|
393
|
-
models: z.ZodOptional<z.
|
|
394
|
-
fable: z.ZodOptional<z.ZodString>;
|
|
395
|
-
opus: z.ZodOptional<z.ZodString>;
|
|
396
|
-
sonnet: z.ZodOptional<z.ZodString>;
|
|
397
|
-
haiku: z.ZodOptional<z.ZodString>;
|
|
398
|
-
}, z.core.$strict>>;
|
|
393
|
+
models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
|
|
399
394
|
effort: z.ZodOptional<z.ZodEnum<{
|
|
400
395
|
none: "none";
|
|
401
396
|
max: "max";
|
|
@@ -661,12 +656,7 @@ declare const ProviderSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
661
656
|
local: "local";
|
|
662
657
|
}>>;
|
|
663
658
|
defaultModel: z.ZodOptional<z.ZodString>;
|
|
664
|
-
models: z.ZodOptional<z.
|
|
665
|
-
fable: z.ZodOptional<z.ZodString>;
|
|
666
|
-
opus: z.ZodOptional<z.ZodString>;
|
|
667
|
-
sonnet: z.ZodOptional<z.ZodString>;
|
|
668
|
-
haiku: z.ZodOptional<z.ZodString>;
|
|
669
|
-
}, z.core.$strict>>;
|
|
659
|
+
models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
|
|
670
660
|
effort: z.ZodOptional<z.ZodEnum<{
|
|
671
661
|
none: "none";
|
|
672
662
|
max: "max";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-use",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.17.0",
|
|
4
4
|
"description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joseph Mearman <joseph@mearman.co.uk>",
|