claude-use 11.19.0 → 11.20.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/README.md +2 -2
- package/dist/cli.cjs +1693 -740
- package/dist/index.cjs +204 -113
- package/dist/index.mjs +202 -111
- package/dist/types/index.d.ts +88 -6
- package/package.json +1 -1
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, 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;
|
|
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, WHOLE_PERCENT_MAX, CompactAtUtilisationSchema, 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";
|
|
@@ -455,10 +455,18 @@ var init_schema = __esm({
|
|
|
455
455
|
PoolMemberSchema = import_zod.z.union([import_zod.z.string().min(1).regex(SELECTOR_RE), import_zod.z.strictObject({ identity: import_zod.z.string().min(1).regex(SELECTOR_RE), when: WhenSchema })]);
|
|
456
456
|
POOL_PREFERENCES = ["score", "listed"];
|
|
457
457
|
PoolPreferenceSchema = import_zod.z.enum(POOL_PREFERENCES);
|
|
458
|
+
WHOLE_PERCENT_MAX = 100;
|
|
459
|
+
CompactAtUtilisationSchema = import_zod.z.number().int().min(1).max(WHOLE_PERCENT_MAX);
|
|
458
460
|
PoolSchema = import_zod.z.strictObject({
|
|
459
461
|
identities: import_zod.z.array(PoolMemberSchema).min(1).refine((members) => new Set(members.map(poolMemberIdentity)).size === members.length, { message: "pool members must be unique" }),
|
|
460
|
-
preference: PoolPreferenceSchema.optional()
|
|
461
|
-
|
|
462
|
+
preference: PoolPreferenceSchema.optional(),
|
|
463
|
+
/** Whether an interactive launch from this pool keeps going when its identity runs out of quota: the launcher moves the session to the next member and resumes the conversation there. Absent means false. */
|
|
464
|
+
resumeOnLimit: import_zod.z.boolean().optional(),
|
|
465
|
+
/** Whether a supervised session's context is compacted before its identity's quota is spent, so the resume on the next member writes a small context instead of a large one. Needs `resumeOnLimit`. Absent means false. */
|
|
466
|
+
compactBeforeLimit: import_zod.z.boolean().optional(),
|
|
467
|
+
/** The share of a quota window, in whole percent, at which sessions are compacted. Absent means the launcher decides from what compacting every session on the member would cost against what its five-hour window has left. Needs `compactBeforeLimit`. */
|
|
468
|
+
compactAtUtilisation: CompactAtUtilisationSchema.optional()
|
|
469
|
+
}).refine((pool) => pool.compactBeforeLimit !== true || pool.resumeOnLimit === true, { message: "compactBeforeLimit needs resumeOnLimit, since a session that is not moved has no cold cache to avoid", path: ["compactBeforeLimit"] }).refine((pool) => pool.compactAtUtilisation === void 0 || pool.compactBeforeLimit === true, { message: "compactAtUtilisation needs compactBeforeLimit", path: ["compactAtUtilisation"] });
|
|
462
470
|
WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
|
463
471
|
AnchorSchema = import_zod.z.strictObject({
|
|
464
472
|
days: import_zod.z.array(import_zod.z.enum(WEEKDAYS)).min(1).refine((days) => new Set(days).size === days.length, "an anchor names each weekday at most once"),
|
|
@@ -2920,7 +2928,7 @@ var init_package = __esm({
|
|
|
2920
2928
|
"package.json"() {
|
|
2921
2929
|
package_default = {
|
|
2922
2930
|
name: "claude-use",
|
|
2923
|
-
version: "11.
|
|
2931
|
+
version: "11.20.0",
|
|
2924
2932
|
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.",
|
|
2925
2933
|
license: "MIT",
|
|
2926
2934
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -5506,10 +5514,12 @@ function rankPool(input) {
|
|
|
5506
5514
|
const warmHere = sticky2?.identity === candidate.identity && nowMs - Date.parse(sticky2.at) <= PROMPT_CACHE_TTL_MS;
|
|
5507
5515
|
if (input.resuming && input.resumeContextTokens !== void 0 && fiveHour !== void 0 && !warmHere) {
|
|
5508
5516
|
const perToken = utilisationPerBilledToken(assessment.member.records);
|
|
5509
|
-
const
|
|
5517
|
+
const committed = input.committedContextTokens?.[candidate.identity] ?? 0;
|
|
5518
|
+
const cost = perToken === void 0 ? void 0 : (input.resumeContextTokens + committed) * perToken;
|
|
5510
5519
|
if (cost !== void 0 && cost > fiveHour.remaining) {
|
|
5511
5520
|
dryAfterMs.push(0);
|
|
5512
|
-
|
|
5521
|
+
const alongside = committed === 0 ? "" : ` (with ${String(committed)} tokens of other conversations already moving here)`;
|
|
5522
|
+
drySpots.push(`resuming a ${String(input.resumeContextTokens)}-token conversation here${alongside} would cost about ${percent(cost)} of the 5h window, which has ${percent(fiveHour.remaining)} left`);
|
|
5513
5523
|
}
|
|
5514
5524
|
}
|
|
5515
5525
|
if (drySpots.length === 0) {
|
|
@@ -5860,6 +5870,7 @@ function rankNamedPool(input, poolName, stack, sticky) {
|
|
|
5860
5870
|
nowMs: input.nowMs,
|
|
5861
5871
|
resuming: input.resuming,
|
|
5862
5872
|
...input.resumeContextTokens === void 0 ? {} : { resumeContextTokens: input.resumeContextTokens },
|
|
5873
|
+
...input.committedContextTokens === void 0 ? {} : { committedContextTokens: input.committedContextTokens },
|
|
5863
5874
|
...sticky === void 0 ? {} : { sticky },
|
|
5864
5875
|
...pool.preference === void 0 ? {} : { preference: pool.preference }
|
|
5865
5876
|
});
|
|
@@ -6029,6 +6040,7 @@ function buildLayoutPaths(root) {
|
|
|
6029
6040
|
usageAnchorsFile: import_node_path23.default.join(root, "usage", "anchors.json"),
|
|
6030
6041
|
usageJobsFile: import_node_path23.default.join(root, "usage", "jobs.json"),
|
|
6031
6042
|
jobLogsDir: import_node_path23.default.join(root, "logs", "jobs"),
|
|
6043
|
+
superviseDir: import_node_path23.default.join(root, "supervise"),
|
|
6032
6044
|
mcpPermissionsFile: import_node_path23.default.join(root, "mcp", "permissions.json")
|
|
6033
6045
|
};
|
|
6034
6046
|
}
|
|
@@ -7631,9 +7643,137 @@ var init_extraFlags = __esm({
|
|
|
7631
7643
|
}
|
|
7632
7644
|
});
|
|
7633
7645
|
|
|
7646
|
+
// src/usage/resumeContext.ts
|
|
7647
|
+
function projectDirNameOf(cwd) {
|
|
7648
|
+
return cwd.replace(/[^A-Za-z0-9]/g, "-");
|
|
7649
|
+
}
|
|
7650
|
+
function resumeTargetOf(passthrough) {
|
|
7651
|
+
const end = passthrough.indexOf("--");
|
|
7652
|
+
const tokens = end === -1 ? passthrough : passthrough.slice(0, end);
|
|
7653
|
+
for (const [index, token] of tokens.entries()) {
|
|
7654
|
+
if (token === "--continue" || token === "-c") {
|
|
7655
|
+
return { kind: "latest" };
|
|
7656
|
+
}
|
|
7657
|
+
if (token === "--resume" || token === "-r") {
|
|
7658
|
+
const next = tokens[index + 1];
|
|
7659
|
+
return next === void 0 || next.startsWith("-") ? void 0 : { kind: "id", id: next };
|
|
7660
|
+
}
|
|
7661
|
+
if (token.startsWith("--resume=")) {
|
|
7662
|
+
const id = token.slice("--resume=".length);
|
|
7663
|
+
return id === "" ? void 0 : { kind: "id", id };
|
|
7664
|
+
}
|
|
7665
|
+
}
|
|
7666
|
+
return void 0;
|
|
7667
|
+
}
|
|
7668
|
+
function countOf(usage, key) {
|
|
7669
|
+
const value = key in usage ? Reflect.get(usage, key) : void 0;
|
|
7670
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
7671
|
+
}
|
|
7672
|
+
function contextTokensOfTranscript(text) {
|
|
7673
|
+
const lines = text.split("\n");
|
|
7674
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
7675
|
+
const line = lines[index];
|
|
7676
|
+
if (line === void 0 || line === "") {
|
|
7677
|
+
continue;
|
|
7678
|
+
}
|
|
7679
|
+
let parsed;
|
|
7680
|
+
try {
|
|
7681
|
+
parsed = JSON.parse(line);
|
|
7682
|
+
} catch {
|
|
7683
|
+
continue;
|
|
7684
|
+
}
|
|
7685
|
+
if (typeof parsed !== "object" || parsed === null || !("type" in parsed) || parsed.type !== "assistant" || !("message" in parsed)) {
|
|
7686
|
+
continue;
|
|
7687
|
+
}
|
|
7688
|
+
const { message } = parsed;
|
|
7689
|
+
if (typeof message !== "object" || message === null || !("usage" in message) || typeof message.usage !== "object" || message.usage === null) {
|
|
7690
|
+
continue;
|
|
7691
|
+
}
|
|
7692
|
+
const { usage } = message;
|
|
7693
|
+
return countOf(usage, "input_tokens") + countOf(usage, "cache_read_input_tokens") + countOf(usage, "cache_creation_input_tokens");
|
|
7694
|
+
}
|
|
7695
|
+
return void 0;
|
|
7696
|
+
}
|
|
7697
|
+
function newestTranscript(fs13, projectDir) {
|
|
7698
|
+
let newest;
|
|
7699
|
+
let newestMs = -Infinity;
|
|
7700
|
+
for (const name of fs13.readdir(projectDir)) {
|
|
7701
|
+
if (!name.endsWith(".jsonl")) {
|
|
7702
|
+
continue;
|
|
7703
|
+
}
|
|
7704
|
+
const candidate = import_node_path37.default.join(projectDir, name);
|
|
7705
|
+
const stat = fs13.lstat(candidate);
|
|
7706
|
+
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
7707
|
+
newestMs = stat.mtimeMs;
|
|
7708
|
+
newest = candidate;
|
|
7709
|
+
}
|
|
7710
|
+
}
|
|
7711
|
+
return newest;
|
|
7712
|
+
}
|
|
7713
|
+
function resumedContextTokens(fs13, params) {
|
|
7714
|
+
const target = resumeTargetOf(params.passthrough);
|
|
7715
|
+
if (target === void 0) {
|
|
7716
|
+
return void 0;
|
|
7717
|
+
}
|
|
7718
|
+
const projectDir = import_node_path37.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
7719
|
+
const file = target.kind === "id" ? import_node_path37.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs13, projectDir);
|
|
7720
|
+
const text = file === void 0 ? void 0 : fs13.readFileUtf8(file);
|
|
7721
|
+
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
7722
|
+
}
|
|
7723
|
+
var import_node_path37;
|
|
7724
|
+
var init_resumeContext = __esm({
|
|
7725
|
+
"src/usage/resumeContext.ts"() {
|
|
7726
|
+
"use strict";
|
|
7727
|
+
import_node_path37 = __toESM(require("node:path"), 1);
|
|
7728
|
+
}
|
|
7729
|
+
});
|
|
7730
|
+
|
|
7731
|
+
// src/launcher/claudeSession.ts
|
|
7732
|
+
function isFlag(token) {
|
|
7733
|
+
return token?.startsWith("-") === true;
|
|
7734
|
+
}
|
|
7735
|
+
function withConversation(passthrough, conversation, id) {
|
|
7736
|
+
const end = passthrough.indexOf(TERMINATOR2);
|
|
7737
|
+
const head = end === -1 ? passthrough : passthrough.slice(0, end);
|
|
7738
|
+
const tail = end === -1 ? [] : passthrough.slice(end);
|
|
7739
|
+
const kept = [];
|
|
7740
|
+
for (let index = 0; index < head.length; index += 1) {
|
|
7741
|
+
const token = head[index];
|
|
7742
|
+
if (token === void 0 || CONTINUE_FLAGS.has(token) || token.startsWith("--resume=") || token.startsWith("--session-id=")) {
|
|
7743
|
+
continue;
|
|
7744
|
+
}
|
|
7745
|
+
if (VALUED_CONVERSATION_FLAGS.has(token)) {
|
|
7746
|
+
if (!isFlag(head[index + 1]) && head[index + 1] !== void 0) {
|
|
7747
|
+
index += 1;
|
|
7748
|
+
}
|
|
7749
|
+
continue;
|
|
7750
|
+
}
|
|
7751
|
+
kept.push(token);
|
|
7752
|
+
}
|
|
7753
|
+
return [...kept, conversation === "start" ? "--session-id" : "--resume", id, ...tail];
|
|
7754
|
+
}
|
|
7755
|
+
function withSupervision(passthrough, supervised) {
|
|
7756
|
+
const conversation = supervised.conversation === "as-given" ? passthrough : withConversation(passthrough, supervised.conversation, supervised.sessionId);
|
|
7757
|
+
if (supervised.settings === void 0) {
|
|
7758
|
+
return conversation;
|
|
7759
|
+
}
|
|
7760
|
+
const end = conversation.indexOf(TERMINATOR2);
|
|
7761
|
+
return end === -1 ? [...conversation, "--settings", supervised.settings] : [...conversation.slice(0, end), "--settings", supervised.settings, ...conversation.slice(end)];
|
|
7762
|
+
}
|
|
7763
|
+
var TERMINATOR2, VALUED_CONVERSATION_FLAGS, CONTINUE_FLAGS;
|
|
7764
|
+
var init_claudeSession = __esm({
|
|
7765
|
+
"src/launcher/claudeSession.ts"() {
|
|
7766
|
+
"use strict";
|
|
7767
|
+
init_resumeContext();
|
|
7768
|
+
TERMINATOR2 = "--";
|
|
7769
|
+
VALUED_CONVERSATION_FLAGS = /* @__PURE__ */ new Set(["--resume", "-r", "--session-id"]);
|
|
7770
|
+
CONTINUE_FLAGS = /* @__PURE__ */ new Set(["--continue", "-c"]);
|
|
7771
|
+
}
|
|
7772
|
+
});
|
|
7773
|
+
|
|
7634
7774
|
// src/launcher/pool.ts
|
|
7635
7775
|
function isResuming(passthrough) {
|
|
7636
|
-
const end = passthrough.indexOf(
|
|
7776
|
+
const end = passthrough.indexOf(TERMINATOR3);
|
|
7637
7777
|
return (end === -1 ? passthrough : passthrough.slice(0, end)).some((token) => RESUME_FLAGS.has(token));
|
|
7638
7778
|
}
|
|
7639
7779
|
function resolvePoolLaunch(params) {
|
|
@@ -7660,6 +7800,7 @@ function resolvePoolLaunch(params) {
|
|
|
7660
7800
|
nowMs,
|
|
7661
7801
|
resuming,
|
|
7662
7802
|
...params.resumeContextTokens === void 0 ? {} : { resumeContextTokens: params.resumeContextTokens },
|
|
7803
|
+
...params.committedContextTokens === void 0 ? {} : { committedContextTokens: params.committedContextTokens },
|
|
7663
7804
|
identityExists: (name) => loadIdentity(params.paths.identitiesDir, name, params.fs) !== void 0,
|
|
7664
7805
|
...stickyRead.sticky === void 0 ? {} : { sticky: stickyRead.sticky }
|
|
7665
7806
|
});
|
|
@@ -7717,7 +7858,7 @@ function resolvePoolLaunch(params) {
|
|
|
7717
7858
|
params.sleep(Math.max(earliestReturn.atMs - nowMs, 0));
|
|
7718
7859
|
}
|
|
7719
7860
|
}
|
|
7720
|
-
var RESUME_FLAGS,
|
|
7861
|
+
var RESUME_FLAGS, TERMINATOR3, REASONS_LOGGED;
|
|
7721
7862
|
var init_pool = __esm({
|
|
7722
7863
|
"src/launcher/pool.ts"() {
|
|
7723
7864
|
"use strict";
|
|
@@ -7725,96 +7866,11 @@ var init_pool = __esm({
|
|
|
7725
7866
|
init_preflight();
|
|
7726
7867
|
init_poolPick();
|
|
7727
7868
|
RESUME_FLAGS = /* @__PURE__ */ new Set(["--continue", "-c", "--resume", "-r"]);
|
|
7728
|
-
|
|
7869
|
+
TERMINATOR3 = "--";
|
|
7729
7870
|
REASONS_LOGGED = 3;
|
|
7730
7871
|
}
|
|
7731
7872
|
});
|
|
7732
7873
|
|
|
7733
|
-
// src/usage/resumeContext.ts
|
|
7734
|
-
function projectDirNameOf(cwd) {
|
|
7735
|
-
return cwd.replace(/[^A-Za-z0-9]/g, "-");
|
|
7736
|
-
}
|
|
7737
|
-
function resumeTargetOf(passthrough) {
|
|
7738
|
-
const end = passthrough.indexOf("--");
|
|
7739
|
-
const tokens = end === -1 ? passthrough : passthrough.slice(0, end);
|
|
7740
|
-
for (const [index, token] of tokens.entries()) {
|
|
7741
|
-
if (token === "--continue" || token === "-c") {
|
|
7742
|
-
return { kind: "latest" };
|
|
7743
|
-
}
|
|
7744
|
-
if (token === "--resume" || token === "-r") {
|
|
7745
|
-
const next = tokens[index + 1];
|
|
7746
|
-
return next === void 0 || next.startsWith("-") ? void 0 : { kind: "id", id: next };
|
|
7747
|
-
}
|
|
7748
|
-
if (token.startsWith("--resume=")) {
|
|
7749
|
-
const id = token.slice("--resume=".length);
|
|
7750
|
-
return id === "" ? void 0 : { kind: "id", id };
|
|
7751
|
-
}
|
|
7752
|
-
}
|
|
7753
|
-
return void 0;
|
|
7754
|
-
}
|
|
7755
|
-
function countOf(usage, key) {
|
|
7756
|
-
const value = key in usage ? Reflect.get(usage, key) : void 0;
|
|
7757
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
7758
|
-
}
|
|
7759
|
-
function contextTokensOfTranscript(text) {
|
|
7760
|
-
const lines = text.split("\n");
|
|
7761
|
-
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
7762
|
-
const line = lines[index];
|
|
7763
|
-
if (line === void 0 || line === "") {
|
|
7764
|
-
continue;
|
|
7765
|
-
}
|
|
7766
|
-
let parsed;
|
|
7767
|
-
try {
|
|
7768
|
-
parsed = JSON.parse(line);
|
|
7769
|
-
} catch {
|
|
7770
|
-
continue;
|
|
7771
|
-
}
|
|
7772
|
-
if (typeof parsed !== "object" || parsed === null || !("type" in parsed) || parsed.type !== "assistant" || !("message" in parsed)) {
|
|
7773
|
-
continue;
|
|
7774
|
-
}
|
|
7775
|
-
const { message } = parsed;
|
|
7776
|
-
if (typeof message !== "object" || message === null || !("usage" in message) || typeof message.usage !== "object" || message.usage === null) {
|
|
7777
|
-
continue;
|
|
7778
|
-
}
|
|
7779
|
-
const { usage } = message;
|
|
7780
|
-
return countOf(usage, "input_tokens") + countOf(usage, "cache_read_input_tokens") + countOf(usage, "cache_creation_input_tokens");
|
|
7781
|
-
}
|
|
7782
|
-
return void 0;
|
|
7783
|
-
}
|
|
7784
|
-
function resumedContextTokens(fs13, params) {
|
|
7785
|
-
const target = resumeTargetOf(params.passthrough);
|
|
7786
|
-
if (target === void 0) {
|
|
7787
|
-
return void 0;
|
|
7788
|
-
}
|
|
7789
|
-
const projectDir = import_node_path37.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
7790
|
-
let file;
|
|
7791
|
-
if (target.kind === "id") {
|
|
7792
|
-
file = import_node_path37.default.join(projectDir, `${target.id}.jsonl`);
|
|
7793
|
-
} else {
|
|
7794
|
-
let newestMs = -Infinity;
|
|
7795
|
-
for (const name of fs13.readdir(projectDir)) {
|
|
7796
|
-
if (!name.endsWith(".jsonl")) {
|
|
7797
|
-
continue;
|
|
7798
|
-
}
|
|
7799
|
-
const candidate = import_node_path37.default.join(projectDir, name);
|
|
7800
|
-
const stat = fs13.lstat(candidate);
|
|
7801
|
-
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
7802
|
-
newestMs = stat.mtimeMs;
|
|
7803
|
-
file = candidate;
|
|
7804
|
-
}
|
|
7805
|
-
}
|
|
7806
|
-
}
|
|
7807
|
-
const text = file === void 0 ? void 0 : fs13.readFileUtf8(file);
|
|
7808
|
-
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
7809
|
-
}
|
|
7810
|
-
var import_node_path37;
|
|
7811
|
-
var init_resumeContext = __esm({
|
|
7812
|
-
"src/usage/resumeContext.ts"() {
|
|
7813
|
-
"use strict";
|
|
7814
|
-
import_node_path37 = __toESM(require("node:path"), 1);
|
|
7815
|
-
}
|
|
7816
|
-
});
|
|
7817
|
-
|
|
7818
7874
|
// src/launcher/spawn.ts
|
|
7819
7875
|
function childExitCode(result) {
|
|
7820
7876
|
if (result.status !== null) {
|
|
@@ -7926,6 +7982,10 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
7926
7982
|
if (decided.pool === void 0) {
|
|
7927
7983
|
return { identityDecision: decided };
|
|
7928
7984
|
}
|
|
7985
|
+
if (params.supervised?.member !== void 0) {
|
|
7986
|
+
const reasons = ["resumed here by the supervising launcher after the previous member ran out of quota"];
|
|
7987
|
+
return { identityDecision: { ...decided, name: params.supervised.member }, poolExplanation: `pool ${decided.pool}: ${reasons.join("; ")}`, poolPick: { name: decided.pool, reasons } };
|
|
7988
|
+
}
|
|
7929
7989
|
const farmRuntime = params.farm;
|
|
7930
7990
|
if (farmRuntime === void 0) {
|
|
7931
7991
|
log.error(`agent-shim: pool "${decided.pool}" was selected, but this launcher has no farm wired to read usage and pick a member with.`);
|
|
@@ -8133,7 +8193,7 @@ function decideLaunch(params, readOnly) {
|
|
|
8133
8193
|
const args = buildArgv({
|
|
8134
8194
|
toolFlags: buildFlagArgs(flags),
|
|
8135
8195
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
8136
|
-
passthrough: parsedArgv.rest
|
|
8196
|
+
passthrough: params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised)
|
|
8137
8197
|
});
|
|
8138
8198
|
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path38.default.join(paths.identitiesDir, identityDecision.name);
|
|
8139
8199
|
const decision = {
|
|
@@ -8245,6 +8305,7 @@ function prepareLaunch(params) {
|
|
|
8245
8305
|
log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor.port)}${resolvedProvider === void 0 ? ` (OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor.connectPort)}, usage recorded)` : ` (provider ${resolvedProvider.name})`}`);
|
|
8246
8306
|
}
|
|
8247
8307
|
const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
|
|
8308
|
+
const sessionId = params.supervised?.sessionId ?? (0, import_node_crypto10.randomUUID)();
|
|
8248
8309
|
const finalEnv = buildEnv({
|
|
8249
8310
|
baseEnv: env,
|
|
8250
8311
|
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
@@ -8254,7 +8315,7 @@ function prepareLaunch(params) {
|
|
|
8254
8315
|
...identityCredential === void 0 ? {} : { identityCredential },
|
|
8255
8316
|
...frontDoor === void 0 ? {} : { frontdoor: frontDoor },
|
|
8256
8317
|
...headroom === void 0 ? {} : { headroom },
|
|
8257
|
-
sessionId
|
|
8318
|
+
sessionId
|
|
8258
8319
|
});
|
|
8259
8320
|
const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
|
|
8260
8321
|
const release = () => {
|
|
@@ -8262,7 +8323,7 @@ function prepareLaunch(params) {
|
|
|
8262
8323
|
registered();
|
|
8263
8324
|
}
|
|
8264
8325
|
};
|
|
8265
|
-
return { bin: decided.bin, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
8326
|
+
return { bin: decided.bin, args: finalArgv, env: finalEnv, sessionId, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
8266
8327
|
}
|
|
8267
8328
|
function resolveLaunch(params) {
|
|
8268
8329
|
const decided = decideLaunch(params, true);
|
|
@@ -8322,6 +8383,7 @@ var init_launcher = __esm({
|
|
|
8322
8383
|
init_identity();
|
|
8323
8384
|
init_flags();
|
|
8324
8385
|
init_extraFlags();
|
|
8386
|
+
init_claudeSession();
|
|
8325
8387
|
init_pool();
|
|
8326
8388
|
init_resumeContext();
|
|
8327
8389
|
init_lock();
|
|
@@ -9164,6 +9226,7 @@ __export(index_exports, {
|
|
|
9164
9226
|
buildRcSetPermissionModePayload: () => buildRcSetPermissionModePayload,
|
|
9165
9227
|
buildRcUserMessagePayload: () => buildRcUserMessagePayload,
|
|
9166
9228
|
carryOver: () => carryOver,
|
|
9229
|
+
changePool: () => changePool,
|
|
9167
9230
|
checkReportHasWarnings: () => checkReportHasWarnings,
|
|
9168
9231
|
checkReportToJson: () => checkReportToJson,
|
|
9169
9232
|
collectCheckReport: () => collectCheckReport,
|
|
@@ -9321,7 +9384,6 @@ __export(index_exports, {
|
|
|
9321
9384
|
setDefaultConfigProfile: () => setDefaultConfigProfile,
|
|
9322
9385
|
setGlobalDefaultProfile: () => setGlobalDefaultProfile,
|
|
9323
9386
|
setIdentityCredential: () => setIdentityCredential,
|
|
9324
|
-
setPool: () => setPool,
|
|
9325
9387
|
setProfileCategories: () => setProfileCategories,
|
|
9326
9388
|
setProfileEntries: () => setProfileEntries,
|
|
9327
9389
|
setProfileLaunchFlags: () => setProfileLaunchFlags,
|
|
@@ -13247,7 +13309,24 @@ function validateMembers(pools, name, members) {
|
|
|
13247
13309
|
throw new UsageError(`Member "pool:${cycle[1] ?? name}" would make pool "${name}" reach itself: ${cycle.join(" -> ")}. A pool cannot nest itself, directly or through another pool.`);
|
|
13248
13310
|
}
|
|
13249
13311
|
}
|
|
13250
|
-
function
|
|
13312
|
+
function requireConsistent(name, pool) {
|
|
13313
|
+
const parsed = PoolSchema.safeParse(pool);
|
|
13314
|
+
if (!parsed.success) {
|
|
13315
|
+
throw new UsageError(`Pool "${name}": ${parsed.error.issues.map((issue) => issue.message).join("; ")}.`);
|
|
13316
|
+
}
|
|
13317
|
+
}
|
|
13318
|
+
function poolPolicyOf(policy) {
|
|
13319
|
+
return {
|
|
13320
|
+
...policy.preference === void 0 ? {} : { preference: policy.preference },
|
|
13321
|
+
...policy.resumeOnLimit === true ? { resumeOnLimit: true } : {},
|
|
13322
|
+
...policy.compactBeforeLimit === true ? { compactBeforeLimit: true } : {},
|
|
13323
|
+
...policy.compactAtUtilisation === void 0 ? {} : { compactAtUtilisation: policy.compactAtUtilisation }
|
|
13324
|
+
};
|
|
13325
|
+
}
|
|
13326
|
+
function isPoolChange(change) {
|
|
13327
|
+
return change.identities !== void 0 || change.preference !== void 0 || change.resumeOnLimit !== void 0 || change.compactBeforeLimit !== void 0 || change.compactAtUtilisation !== void 0;
|
|
13328
|
+
}
|
|
13329
|
+
function addPool(paths, name, identities, policy = {}) {
|
|
13251
13330
|
if (!PoolNameSchema.safeParse(name).success) {
|
|
13252
13331
|
throw new InvalidPoolNameError(name);
|
|
13253
13332
|
}
|
|
@@ -13256,14 +13335,21 @@ function addPool(paths, name, identities, preference) {
|
|
|
13256
13335
|
throw new PoolAlreadyExistsError(name);
|
|
13257
13336
|
}
|
|
13258
13337
|
validateMembers(pools, name, identities);
|
|
13259
|
-
const pool = { identities: [...identities], ...
|
|
13338
|
+
const pool = { identities: [...identities], ...poolPolicyOf(policy) };
|
|
13339
|
+
requireConsistent(name, pool);
|
|
13260
13340
|
writePools(paths, { ...pools, [name]: pool });
|
|
13261
13341
|
return pool;
|
|
13262
13342
|
}
|
|
13263
|
-
function
|
|
13264
|
-
requirePool(paths, name);
|
|
13343
|
+
function changePool(paths, name, change) {
|
|
13344
|
+
const existing = requirePool(paths, name);
|
|
13345
|
+
const identities = change.identities ?? existing.identities;
|
|
13265
13346
|
validateMembers(readPools(paths), name, identities);
|
|
13266
|
-
const
|
|
13347
|
+
const preference = change.preference === void 0 ? existing.preference : change.preference === false ? void 0 : change.preference;
|
|
13348
|
+
const resumeOnLimit = change.resumeOnLimit ?? existing.resumeOnLimit;
|
|
13349
|
+
const compactBeforeLimit = change.compactBeforeLimit ?? existing.compactBeforeLimit;
|
|
13350
|
+
const compactAtUtilisation = change.compactAtUtilisation === void 0 ? existing.compactAtUtilisation : change.compactAtUtilisation === false ? void 0 : change.compactAtUtilisation;
|
|
13351
|
+
const pool = { identities: [...identities], ...poolPolicyOf({ preference, resumeOnLimit, compactBeforeLimit, compactAtUtilisation }) };
|
|
13352
|
+
requireConsistent(name, pool);
|
|
13267
13353
|
writePools(paths, { ...readPools(paths), [name]: pool });
|
|
13268
13354
|
return pool;
|
|
13269
13355
|
}
|
|
@@ -15394,13 +15480,19 @@ var PoolMembersInputSchema = import_zod24.z.array(import_zod24.z.string().min(1)
|
|
|
15394
15480
|
var ConfigPoolAddInputSchema = import_zod24.z.strictObject({
|
|
15395
15481
|
name: import_zod24.z.string().min(1),
|
|
15396
15482
|
identities: PoolMembersInputSchema,
|
|
15397
|
-
preference: import_zod24.z.enum(POOL_PREFERENCES).optional()
|
|
15483
|
+
preference: import_zod24.z.enum(POOL_PREFERENCES).optional(),
|
|
15484
|
+
resumeOnLimit: import_zod24.z.boolean().optional(),
|
|
15485
|
+
compactBeforeLimit: import_zod24.z.boolean().optional(),
|
|
15486
|
+
compactAtUtilisation: CompactAtUtilisationSchema.optional()
|
|
15398
15487
|
});
|
|
15399
15488
|
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
15400
15489
|
var ConfigPoolSetInputSchema = import_zod24.z.strictObject({
|
|
15401
15490
|
name: import_zod24.z.string().min(1),
|
|
15402
15491
|
identities: PoolMembersInputSchema.optional(),
|
|
15403
|
-
preference: import_zod24.z.union([import_zod24.z.enum(POOL_PREFERENCES), import_zod24.z.literal(false)]).optional()
|
|
15492
|
+
preference: import_zod24.z.union([import_zod24.z.enum(POOL_PREFERENCES), import_zod24.z.literal(false)]).optional(),
|
|
15493
|
+
resumeOnLimit: import_zod24.z.boolean().optional(),
|
|
15494
|
+
compactBeforeLimit: import_zod24.z.boolean().optional(),
|
|
15495
|
+
compactAtUtilisation: import_zod24.z.union([CompactAtUtilisationSchema, import_zod24.z.literal(false)]).optional()
|
|
15404
15496
|
});
|
|
15405
15497
|
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
15406
15498
|
var ConfigPoolRemoveInputSchema = import_zod24.z.strictObject({ name: import_zod24.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
@@ -15611,20 +15703,19 @@ function createConfigApiRouter(deps) {
|
|
|
15611
15703
|
add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
|
|
15612
15704
|
({ input }) => guarded(() => {
|
|
15613
15705
|
requireIdentityNames(paths, input.identities);
|
|
15614
|
-
const created = addPool(paths, input.name, input.identities, input.preference);
|
|
15706
|
+
const created = addPool(paths, input.name, input.identities, { preference: input.preference, resumeOnLimit: input.resumeOnLimit, compactBeforeLimit: input.compactBeforeLimit, compactAtUtilisation: input.compactAtUtilisation });
|
|
15615
15707
|
return { action: "created", kind: "pool", name: input.name, value: created };
|
|
15616
15708
|
})
|
|
15617
15709
|
),
|
|
15618
|
-
set: route("/rest/config/pool/set", "Replace a pool's members, its preference or
|
|
15710
|
+
set: route("/rest/config/pool/set", "Replace a pool's members, change its preference or whether it resumes on a spent quota").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
|
|
15619
15711
|
({ input }) => guarded(() => {
|
|
15620
|
-
|
|
15621
|
-
|
|
15712
|
+
const change = { identities: input.identities, preference: input.preference, resumeOnLimit: input.resumeOnLimit, compactBeforeLimit: input.compactBeforeLimit, compactAtUtilisation: input.compactAtUtilisation };
|
|
15713
|
+
requireChange(isPoolChange(change), "identities, preference, resumeOnLimit, compactBeforeLimit or compactAtUtilisation");
|
|
15714
|
+
requirePool(paths, input.name);
|
|
15622
15715
|
if (input.identities !== void 0) {
|
|
15623
15716
|
requireIdentityNames(paths, input.identities);
|
|
15624
15717
|
}
|
|
15625
|
-
|
|
15626
|
-
const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
|
|
15627
|
-
return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
|
|
15718
|
+
return { action: "updated", kind: "pool", name: input.name, value: changePool(paths, input.name, change) };
|
|
15628
15719
|
})
|
|
15629
15720
|
),
|
|
15630
15721
|
remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
|
|
@@ -18841,6 +18932,7 @@ init_ownCli();
|
|
|
18841
18932
|
buildRcSetPermissionModePayload,
|
|
18842
18933
|
buildRcUserMessagePayload,
|
|
18843
18934
|
carryOver,
|
|
18935
|
+
changePool,
|
|
18844
18936
|
checkReportHasWarnings,
|
|
18845
18937
|
checkReportToJson,
|
|
18846
18938
|
collectCheckReport,
|
|
@@ -18998,7 +19090,6 @@ init_ownCli();
|
|
|
18998
19090
|
setDefaultConfigProfile,
|
|
18999
19091
|
setGlobalDefaultProfile,
|
|
19000
19092
|
setIdentityCredential,
|
|
19001
|
-
setPool,
|
|
19002
19093
|
setProfileCategories,
|
|
19003
19094
|
setProfileEntries,
|
|
19004
19095
|
setProfileLaunchFlags,
|