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.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.19.0",
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 cost = perToken === void 0 ? void 0 : input.resumeContextTokens * perToken;
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
- 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`);
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(TERMINATOR2);
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, TERMINATOR2, REASONS_LOGGED;
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
- TERMINATOR2 = "--";
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: (0, import_node_crypto10.randomUUID)()
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 addPool(paths, name, identities, preference) {
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], ...preference === void 0 ? {} : { preference } };
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 setPool(paths, name, identities, preference) {
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 pool = { identities: [...identities], ...preference === void 0 ? {} : { preference } };
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 both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
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
- requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
15621
- const existing = requirePool(paths, input.name);
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
- const members = input.identities ?? existing.identities;
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,