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/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, 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;
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, 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;
227
227
  var init_schema = __esm({
228
228
  "src/config/schema.ts"() {
229
229
  "use strict";
@@ -433,10 +433,18 @@ var init_schema = __esm({
433
433
  PoolMemberSchema = z.union([z.string().min(1).regex(SELECTOR_RE), z.strictObject({ identity: z.string().min(1).regex(SELECTOR_RE), when: WhenSchema })]);
434
434
  POOL_PREFERENCES = ["score", "listed"];
435
435
  PoolPreferenceSchema = z.enum(POOL_PREFERENCES);
436
+ WHOLE_PERCENT_MAX = 100;
437
+ CompactAtUtilisationSchema = z.number().int().min(1).max(WHOLE_PERCENT_MAX);
436
438
  PoolSchema = z.strictObject({
437
439
  identities: z.array(PoolMemberSchema).min(1).refine((members) => new Set(members.map(poolMemberIdentity)).size === members.length, { message: "pool members must be unique" }),
438
- preference: PoolPreferenceSchema.optional()
439
- });
440
+ preference: PoolPreferenceSchema.optional(),
441
+ /** 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. */
442
+ resumeOnLimit: z.boolean().optional(),
443
+ /** 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. */
444
+ compactBeforeLimit: z.boolean().optional(),
445
+ /** 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`. */
446
+ compactAtUtilisation: CompactAtUtilisationSchema.optional()
447
+ }).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"] });
440
448
  WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
441
449
  AnchorSchema = z.strictObject({
442
450
  days: z.array(z.enum(WEEKDAYS)).min(1).refine((days) => new Set(days).size === days.length, "an anchor names each weekday at most once"),
@@ -2896,7 +2904,7 @@ var init_package = __esm({
2896
2904
  "package.json"() {
2897
2905
  package_default = {
2898
2906
  name: "claude-use",
2899
- version: "11.19.0",
2907
+ version: "11.20.0",
2900
2908
  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.",
2901
2909
  license: "MIT",
2902
2910
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -5480,10 +5488,12 @@ function rankPool(input) {
5480
5488
  const warmHere = sticky2?.identity === candidate.identity && nowMs - Date.parse(sticky2.at) <= PROMPT_CACHE_TTL_MS;
5481
5489
  if (input.resuming && input.resumeContextTokens !== void 0 && fiveHour !== void 0 && !warmHere) {
5482
5490
  const perToken = utilisationPerBilledToken(assessment.member.records);
5483
- const cost = perToken === void 0 ? void 0 : input.resumeContextTokens * perToken;
5491
+ const committed = input.committedContextTokens?.[candidate.identity] ?? 0;
5492
+ const cost = perToken === void 0 ? void 0 : (input.resumeContextTokens + committed) * perToken;
5484
5493
  if (cost !== void 0 && cost > fiveHour.remaining) {
5485
5494
  dryAfterMs.push(0);
5486
- drySpots.push(`resuming a ${String(input.resumeContextTokens)}-token conversation here would cost about ${percent(cost)} of the 5h window, which has ${percent(fiveHour.remaining)} left`);
5495
+ const alongside = committed === 0 ? "" : ` (with ${String(committed)} tokens of other conversations already moving here)`;
5496
+ 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`);
5487
5497
  }
5488
5498
  }
5489
5499
  if (drySpots.length === 0) {
@@ -5836,6 +5846,7 @@ function rankNamedPool(input, poolName, stack, sticky) {
5836
5846
  nowMs: input.nowMs,
5837
5847
  resuming: input.resuming,
5838
5848
  ...input.resumeContextTokens === void 0 ? {} : { resumeContextTokens: input.resumeContextTokens },
5849
+ ...input.committedContextTokens === void 0 ? {} : { committedContextTokens: input.committedContextTokens },
5839
5850
  ...sticky === void 0 ? {} : { sticky },
5840
5851
  ...pool.preference === void 0 ? {} : { preference: pool.preference }
5841
5852
  });
@@ -6006,6 +6017,7 @@ function buildLayoutPaths(root) {
6006
6017
  usageAnchorsFile: path23.join(root, "usage", "anchors.json"),
6007
6018
  usageJobsFile: path23.join(root, "usage", "jobs.json"),
6008
6019
  jobLogsDir: path23.join(root, "logs", "jobs"),
6020
+ superviseDir: path23.join(root, "supervise"),
6009
6021
  mcpPermissionsFile: path23.join(root, "mcp", "permissions.json")
6010
6022
  };
6011
6023
  }
@@ -7604,9 +7616,136 @@ var init_extraFlags = __esm({
7604
7616
  }
7605
7617
  });
7606
7618
 
7619
+ // src/usage/resumeContext.ts
7620
+ import path37 from "node:path";
7621
+ function projectDirNameOf(cwd) {
7622
+ return cwd.replace(/[^A-Za-z0-9]/g, "-");
7623
+ }
7624
+ function resumeTargetOf(passthrough) {
7625
+ const end = passthrough.indexOf("--");
7626
+ const tokens = end === -1 ? passthrough : passthrough.slice(0, end);
7627
+ for (const [index, token] of tokens.entries()) {
7628
+ if (token === "--continue" || token === "-c") {
7629
+ return { kind: "latest" };
7630
+ }
7631
+ if (token === "--resume" || token === "-r") {
7632
+ const next = tokens[index + 1];
7633
+ return next === void 0 || next.startsWith("-") ? void 0 : { kind: "id", id: next };
7634
+ }
7635
+ if (token.startsWith("--resume=")) {
7636
+ const id = token.slice("--resume=".length);
7637
+ return id === "" ? void 0 : { kind: "id", id };
7638
+ }
7639
+ }
7640
+ return void 0;
7641
+ }
7642
+ function countOf(usage, key) {
7643
+ const value = key in usage ? Reflect.get(usage, key) : void 0;
7644
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
7645
+ }
7646
+ function contextTokensOfTranscript(text) {
7647
+ const lines = text.split("\n");
7648
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
7649
+ const line = lines[index];
7650
+ if (line === void 0 || line === "") {
7651
+ continue;
7652
+ }
7653
+ let parsed;
7654
+ try {
7655
+ parsed = JSON.parse(line);
7656
+ } catch {
7657
+ continue;
7658
+ }
7659
+ if (typeof parsed !== "object" || parsed === null || !("type" in parsed) || parsed.type !== "assistant" || !("message" in parsed)) {
7660
+ continue;
7661
+ }
7662
+ const { message } = parsed;
7663
+ if (typeof message !== "object" || message === null || !("usage" in message) || typeof message.usage !== "object" || message.usage === null) {
7664
+ continue;
7665
+ }
7666
+ const { usage } = message;
7667
+ return countOf(usage, "input_tokens") + countOf(usage, "cache_read_input_tokens") + countOf(usage, "cache_creation_input_tokens");
7668
+ }
7669
+ return void 0;
7670
+ }
7671
+ function newestTranscript(fs13, projectDir) {
7672
+ let newest;
7673
+ let newestMs = -Infinity;
7674
+ for (const name of fs13.readdir(projectDir)) {
7675
+ if (!name.endsWith(".jsonl")) {
7676
+ continue;
7677
+ }
7678
+ const candidate = path37.join(projectDir, name);
7679
+ const stat = fs13.lstat(candidate);
7680
+ if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
7681
+ newestMs = stat.mtimeMs;
7682
+ newest = candidate;
7683
+ }
7684
+ }
7685
+ return newest;
7686
+ }
7687
+ function resumedContextTokens(fs13, params) {
7688
+ const target = resumeTargetOf(params.passthrough);
7689
+ if (target === void 0) {
7690
+ return void 0;
7691
+ }
7692
+ const projectDir = path37.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
7693
+ const file = target.kind === "id" ? path37.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs13, projectDir);
7694
+ const text = file === void 0 ? void 0 : fs13.readFileUtf8(file);
7695
+ return text === void 0 ? void 0 : contextTokensOfTranscript(text);
7696
+ }
7697
+ var init_resumeContext = __esm({
7698
+ "src/usage/resumeContext.ts"() {
7699
+ "use strict";
7700
+ }
7701
+ });
7702
+
7703
+ // src/launcher/claudeSession.ts
7704
+ function isFlag(token) {
7705
+ return token?.startsWith("-") === true;
7706
+ }
7707
+ function withConversation(passthrough, conversation, id) {
7708
+ const end = passthrough.indexOf(TERMINATOR2);
7709
+ const head = end === -1 ? passthrough : passthrough.slice(0, end);
7710
+ const tail = end === -1 ? [] : passthrough.slice(end);
7711
+ const kept = [];
7712
+ for (let index = 0; index < head.length; index += 1) {
7713
+ const token = head[index];
7714
+ if (token === void 0 || CONTINUE_FLAGS.has(token) || token.startsWith("--resume=") || token.startsWith("--session-id=")) {
7715
+ continue;
7716
+ }
7717
+ if (VALUED_CONVERSATION_FLAGS.has(token)) {
7718
+ if (!isFlag(head[index + 1]) && head[index + 1] !== void 0) {
7719
+ index += 1;
7720
+ }
7721
+ continue;
7722
+ }
7723
+ kept.push(token);
7724
+ }
7725
+ return [...kept, conversation === "start" ? "--session-id" : "--resume", id, ...tail];
7726
+ }
7727
+ function withSupervision(passthrough, supervised) {
7728
+ const conversation = supervised.conversation === "as-given" ? passthrough : withConversation(passthrough, supervised.conversation, supervised.sessionId);
7729
+ if (supervised.settings === void 0) {
7730
+ return conversation;
7731
+ }
7732
+ const end = conversation.indexOf(TERMINATOR2);
7733
+ return end === -1 ? [...conversation, "--settings", supervised.settings] : [...conversation.slice(0, end), "--settings", supervised.settings, ...conversation.slice(end)];
7734
+ }
7735
+ var TERMINATOR2, VALUED_CONVERSATION_FLAGS, CONTINUE_FLAGS;
7736
+ var init_claudeSession = __esm({
7737
+ "src/launcher/claudeSession.ts"() {
7738
+ "use strict";
7739
+ init_resumeContext();
7740
+ TERMINATOR2 = "--";
7741
+ VALUED_CONVERSATION_FLAGS = /* @__PURE__ */ new Set(["--resume", "-r", "--session-id"]);
7742
+ CONTINUE_FLAGS = /* @__PURE__ */ new Set(["--continue", "-c"]);
7743
+ }
7744
+ });
7745
+
7607
7746
  // src/launcher/pool.ts
7608
7747
  function isResuming(passthrough) {
7609
- const end = passthrough.indexOf(TERMINATOR2);
7748
+ const end = passthrough.indexOf(TERMINATOR3);
7610
7749
  return (end === -1 ? passthrough : passthrough.slice(0, end)).some((token) => RESUME_FLAGS.has(token));
7611
7750
  }
7612
7751
  function resolvePoolLaunch(params) {
@@ -7633,6 +7772,7 @@ function resolvePoolLaunch(params) {
7633
7772
  nowMs,
7634
7773
  resuming,
7635
7774
  ...params.resumeContextTokens === void 0 ? {} : { resumeContextTokens: params.resumeContextTokens },
7775
+ ...params.committedContextTokens === void 0 ? {} : { committedContextTokens: params.committedContextTokens },
7636
7776
  identityExists: (name) => loadIdentity(params.paths.identitiesDir, name, params.fs) !== void 0,
7637
7777
  ...stickyRead.sticky === void 0 ? {} : { sticky: stickyRead.sticky }
7638
7778
  });
@@ -7690,7 +7830,7 @@ function resolvePoolLaunch(params) {
7690
7830
  params.sleep(Math.max(earliestReturn.atMs - nowMs, 0));
7691
7831
  }
7692
7832
  }
7693
- var RESUME_FLAGS, TERMINATOR2, REASONS_LOGGED;
7833
+ var RESUME_FLAGS, TERMINATOR3, REASONS_LOGGED;
7694
7834
  var init_pool = __esm({
7695
7835
  "src/launcher/pool.ts"() {
7696
7836
  "use strict";
@@ -7698,95 +7838,11 @@ var init_pool = __esm({
7698
7838
  init_preflight();
7699
7839
  init_poolPick();
7700
7840
  RESUME_FLAGS = /* @__PURE__ */ new Set(["--continue", "-c", "--resume", "-r"]);
7701
- TERMINATOR2 = "--";
7841
+ TERMINATOR3 = "--";
7702
7842
  REASONS_LOGGED = 3;
7703
7843
  }
7704
7844
  });
7705
7845
 
7706
- // src/usage/resumeContext.ts
7707
- import path37 from "node:path";
7708
- function projectDirNameOf(cwd) {
7709
- return cwd.replace(/[^A-Za-z0-9]/g, "-");
7710
- }
7711
- function resumeTargetOf(passthrough) {
7712
- const end = passthrough.indexOf("--");
7713
- const tokens = end === -1 ? passthrough : passthrough.slice(0, end);
7714
- for (const [index, token] of tokens.entries()) {
7715
- if (token === "--continue" || token === "-c") {
7716
- return { kind: "latest" };
7717
- }
7718
- if (token === "--resume" || token === "-r") {
7719
- const next = tokens[index + 1];
7720
- return next === void 0 || next.startsWith("-") ? void 0 : { kind: "id", id: next };
7721
- }
7722
- if (token.startsWith("--resume=")) {
7723
- const id = token.slice("--resume=".length);
7724
- return id === "" ? void 0 : { kind: "id", id };
7725
- }
7726
- }
7727
- return void 0;
7728
- }
7729
- function countOf(usage, key) {
7730
- const value = key in usage ? Reflect.get(usage, key) : void 0;
7731
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
7732
- }
7733
- function contextTokensOfTranscript(text) {
7734
- const lines = text.split("\n");
7735
- for (let index = lines.length - 1; index >= 0; index -= 1) {
7736
- const line = lines[index];
7737
- if (line === void 0 || line === "") {
7738
- continue;
7739
- }
7740
- let parsed;
7741
- try {
7742
- parsed = JSON.parse(line);
7743
- } catch {
7744
- continue;
7745
- }
7746
- if (typeof parsed !== "object" || parsed === null || !("type" in parsed) || parsed.type !== "assistant" || !("message" in parsed)) {
7747
- continue;
7748
- }
7749
- const { message } = parsed;
7750
- if (typeof message !== "object" || message === null || !("usage" in message) || typeof message.usage !== "object" || message.usage === null) {
7751
- continue;
7752
- }
7753
- const { usage } = message;
7754
- return countOf(usage, "input_tokens") + countOf(usage, "cache_read_input_tokens") + countOf(usage, "cache_creation_input_tokens");
7755
- }
7756
- return void 0;
7757
- }
7758
- function resumedContextTokens(fs13, params) {
7759
- const target = resumeTargetOf(params.passthrough);
7760
- if (target === void 0) {
7761
- return void 0;
7762
- }
7763
- const projectDir = path37.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
7764
- let file;
7765
- if (target.kind === "id") {
7766
- file = path37.join(projectDir, `${target.id}.jsonl`);
7767
- } else {
7768
- let newestMs = -Infinity;
7769
- for (const name of fs13.readdir(projectDir)) {
7770
- if (!name.endsWith(".jsonl")) {
7771
- continue;
7772
- }
7773
- const candidate = path37.join(projectDir, name);
7774
- const stat = fs13.lstat(candidate);
7775
- if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
7776
- newestMs = stat.mtimeMs;
7777
- file = candidate;
7778
- }
7779
- }
7780
- }
7781
- const text = file === void 0 ? void 0 : fs13.readFileUtf8(file);
7782
- return text === void 0 ? void 0 : contextTokensOfTranscript(text);
7783
- }
7784
- var init_resumeContext = __esm({
7785
- "src/usage/resumeContext.ts"() {
7786
- "use strict";
7787
- }
7788
- });
7789
-
7790
7846
  // src/launcher/spawn.ts
7791
7847
  import os7 from "node:os";
7792
7848
  function childExitCode(result) {
@@ -7900,6 +7956,10 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
7900
7956
  if (decided.pool === void 0) {
7901
7957
  return { identityDecision: decided };
7902
7958
  }
7959
+ if (params.supervised?.member !== void 0) {
7960
+ const reasons = ["resumed here by the supervising launcher after the previous member ran out of quota"];
7961
+ return { identityDecision: { ...decided, name: params.supervised.member }, poolExplanation: `pool ${decided.pool}: ${reasons.join("; ")}`, poolPick: { name: decided.pool, reasons } };
7962
+ }
7903
7963
  const farmRuntime = params.farm;
7904
7964
  if (farmRuntime === void 0) {
7905
7965
  log.error(`agent-shim: pool "${decided.pool}" was selected, but this launcher has no farm wired to read usage and pick a member with.`);
@@ -8107,7 +8167,7 @@ function decideLaunch(params, readOnly) {
8107
8167
  const args = buildArgv({
8108
8168
  toolFlags: buildFlagArgs(flags),
8109
8169
  extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
8110
- passthrough: parsedArgv.rest
8170
+ passthrough: params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised)
8111
8171
  });
8112
8172
  const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path38.join(paths.identitiesDir, identityDecision.name);
8113
8173
  const decision = {
@@ -8219,6 +8279,7 @@ function prepareLaunch(params) {
8219
8279
  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})`}`);
8220
8280
  }
8221
8281
  const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
8282
+ const sessionId = params.supervised?.sessionId ?? randomUUID4();
8222
8283
  const finalEnv = buildEnv({
8223
8284
  baseEnv: env,
8224
8285
  configDirEscapeHatch: configDirEscapeHatchApplies,
@@ -8228,7 +8289,7 @@ function prepareLaunch(params) {
8228
8289
  ...identityCredential === void 0 ? {} : { identityCredential },
8229
8290
  ...frontDoor === void 0 ? {} : { frontdoor: frontDoor },
8230
8291
  ...headroom === void 0 ? {} : { headroom },
8231
- sessionId: randomUUID4()
8292
+ sessionId
8232
8293
  });
8233
8294
  const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
8234
8295
  const release = () => {
@@ -8236,7 +8297,7 @@ function prepareLaunch(params) {
8236
8297
  registered();
8237
8298
  }
8238
8299
  };
8239
- return { bin: decided.bin, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
8300
+ return { bin: decided.bin, args: finalArgv, env: finalEnv, sessionId, release, markChildStarted: updateCheck.markChildStarted, decision };
8240
8301
  }
8241
8302
  function resolveLaunch(params) {
8242
8303
  const decided = decideLaunch(params, true);
@@ -8293,6 +8354,7 @@ var init_launcher = __esm({
8293
8354
  init_identity();
8294
8355
  init_flags();
8295
8356
  init_extraFlags();
8357
+ init_claudeSession();
8296
8358
  init_pool();
8297
8359
  init_resumeContext();
8298
8360
  init_lock();
@@ -12834,7 +12896,24 @@ function validateMembers(pools, name, members) {
12834
12896
  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.`);
12835
12897
  }
12836
12898
  }
12837
- function addPool(paths, name, identities, preference) {
12899
+ function requireConsistent(name, pool) {
12900
+ const parsed = PoolSchema.safeParse(pool);
12901
+ if (!parsed.success) {
12902
+ throw new UsageError(`Pool "${name}": ${parsed.error.issues.map((issue) => issue.message).join("; ")}.`);
12903
+ }
12904
+ }
12905
+ function poolPolicyOf(policy) {
12906
+ return {
12907
+ ...policy.preference === void 0 ? {} : { preference: policy.preference },
12908
+ ...policy.resumeOnLimit === true ? { resumeOnLimit: true } : {},
12909
+ ...policy.compactBeforeLimit === true ? { compactBeforeLimit: true } : {},
12910
+ ...policy.compactAtUtilisation === void 0 ? {} : { compactAtUtilisation: policy.compactAtUtilisation }
12911
+ };
12912
+ }
12913
+ function isPoolChange(change) {
12914
+ return change.identities !== void 0 || change.preference !== void 0 || change.resumeOnLimit !== void 0 || change.compactBeforeLimit !== void 0 || change.compactAtUtilisation !== void 0;
12915
+ }
12916
+ function addPool(paths, name, identities, policy = {}) {
12838
12917
  if (!PoolNameSchema.safeParse(name).success) {
12839
12918
  throw new InvalidPoolNameError(name);
12840
12919
  }
@@ -12843,14 +12922,21 @@ function addPool(paths, name, identities, preference) {
12843
12922
  throw new PoolAlreadyExistsError(name);
12844
12923
  }
12845
12924
  validateMembers(pools, name, identities);
12846
- const pool = { identities: [...identities], ...preference === void 0 ? {} : { preference } };
12925
+ const pool = { identities: [...identities], ...poolPolicyOf(policy) };
12926
+ requireConsistent(name, pool);
12847
12927
  writePools(paths, { ...pools, [name]: pool });
12848
12928
  return pool;
12849
12929
  }
12850
- function setPool(paths, name, identities, preference) {
12851
- requirePool(paths, name);
12930
+ function changePool(paths, name, change) {
12931
+ const existing = requirePool(paths, name);
12932
+ const identities = change.identities ?? existing.identities;
12852
12933
  validateMembers(readPools(paths), name, identities);
12853
- const pool = { identities: [...identities], ...preference === void 0 ? {} : { preference } };
12934
+ const preference = change.preference === void 0 ? existing.preference : change.preference === false ? void 0 : change.preference;
12935
+ const resumeOnLimit = change.resumeOnLimit ?? existing.resumeOnLimit;
12936
+ const compactBeforeLimit = change.compactBeforeLimit ?? existing.compactBeforeLimit;
12937
+ const compactAtUtilisation = change.compactAtUtilisation === void 0 ? existing.compactAtUtilisation : change.compactAtUtilisation === false ? void 0 : change.compactAtUtilisation;
12938
+ const pool = { identities: [...identities], ...poolPolicyOf({ preference, resumeOnLimit, compactBeforeLimit, compactAtUtilisation }) };
12939
+ requireConsistent(name, pool);
12854
12940
  writePools(paths, { ...readPools(paths), [name]: pool });
12855
12941
  return pool;
12856
12942
  }
@@ -14981,13 +15067,19 @@ var PoolMembersInputSchema = z24.array(z24.string().min(1)).min(1);
14981
15067
  var ConfigPoolAddInputSchema = z24.strictObject({
14982
15068
  name: z24.string().min(1),
14983
15069
  identities: PoolMembersInputSchema,
14984
- preference: z24.enum(POOL_PREFERENCES).optional()
15070
+ preference: z24.enum(POOL_PREFERENCES).optional(),
15071
+ resumeOnLimit: z24.boolean().optional(),
15072
+ compactBeforeLimit: z24.boolean().optional(),
15073
+ compactAtUtilisation: CompactAtUtilisationSchema.optional()
14985
15074
  });
14986
15075
  var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
14987
15076
  var ConfigPoolSetInputSchema = z24.strictObject({
14988
15077
  name: z24.string().min(1),
14989
15078
  identities: PoolMembersInputSchema.optional(),
14990
- preference: z24.union([z24.enum(POOL_PREFERENCES), z24.literal(false)]).optional()
15079
+ preference: z24.union([z24.enum(POOL_PREFERENCES), z24.literal(false)]).optional(),
15080
+ resumeOnLimit: z24.boolean().optional(),
15081
+ compactBeforeLimit: z24.boolean().optional(),
15082
+ compactAtUtilisation: z24.union([CompactAtUtilisationSchema, z24.literal(false)]).optional()
14991
15083
  });
14992
15084
  var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
14993
15085
  var ConfigPoolRemoveInputSchema = z24.strictObject({ name: z24.string().min(1), confirm: RemovalConfirmationSchema });
@@ -15198,20 +15290,19 @@ function createConfigApiRouter(deps) {
15198
15290
  add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
15199
15291
  ({ input }) => guarded(() => {
15200
15292
  requireIdentityNames(paths, input.identities);
15201
- const created = addPool(paths, input.name, input.identities, input.preference);
15293
+ const created = addPool(paths, input.name, input.identities, { preference: input.preference, resumeOnLimit: input.resumeOnLimit, compactBeforeLimit: input.compactBeforeLimit, compactAtUtilisation: input.compactAtUtilisation });
15202
15294
  return { action: "created", kind: "pool", name: input.name, value: created };
15203
15295
  })
15204
15296
  ),
15205
- set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
15297
+ 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(
15206
15298
  ({ input }) => guarded(() => {
15207
- requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
15208
- const existing = requirePool(paths, input.name);
15299
+ const change = { identities: input.identities, preference: input.preference, resumeOnLimit: input.resumeOnLimit, compactBeforeLimit: input.compactBeforeLimit, compactAtUtilisation: input.compactAtUtilisation };
15300
+ requireChange(isPoolChange(change), "identities, preference, resumeOnLimit, compactBeforeLimit or compactAtUtilisation");
15301
+ requirePool(paths, input.name);
15209
15302
  if (input.identities !== void 0) {
15210
15303
  requireIdentityNames(paths, input.identities);
15211
15304
  }
15212
- const members = input.identities ?? existing.identities;
15213
- const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
15214
- return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
15305
+ return { action: "updated", kind: "pool", name: input.name, value: changePool(paths, input.name, change) };
15215
15306
  })
15216
15307
  ),
15217
15308
  remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
@@ -18427,6 +18518,7 @@ export {
18427
18518
  buildRcSetPermissionModePayload,
18428
18519
  buildRcUserMessagePayload,
18429
18520
  carryOver,
18521
+ changePool,
18430
18522
  checkReportHasWarnings,
18431
18523
  checkReportToJson,
18432
18524
  collectCheckReport,
@@ -18584,7 +18676,6 @@ export {
18584
18676
  setDefaultConfigProfile,
18585
18677
  setGlobalDefaultProfile,
18586
18678
  setIdentityCredential,
18587
- setPool,
18588
18679
  setProfileCategories,
18589
18680
  setProfileEntries,
18590
18681
  setProfileLaunchFlags,