claude-use 9.13.0 → 9.14.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
@@ -228,7 +228,15 @@ function isCodexProvider(provider) {
228
228
  function poolMemberIdentity(member) {
229
229
  return typeof member === "string" ? member : member.identity;
230
230
  }
231
- 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, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, 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;
231
+ function isTimeZone(name) {
232
+ try {
233
+ new Intl.DateTimeFormat("en", { timeZone: name });
234
+ return true;
235
+ } catch {
236
+ return false;
237
+ }
238
+ }
239
+ 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, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, 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, WEEKDAYS, AnchorSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
232
240
  var init_schema = __esm({
233
241
  "src/config/schema.ts"() {
234
242
  "use strict";
@@ -468,12 +476,20 @@ var init_schema = __esm({
468
476
  update: UpdateGlobalConfigSchema.optional(),
469
477
  pools: import_zod.z.record(PoolNameSchema, PoolSchema).optional()
470
478
  });
479
+ WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
480
+ AnchorSchema = import_zod.z.strictObject({
481
+ 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"),
482
+ time: import_zod.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a 24-hour time such as 06:00"),
483
+ timeZone: import_zod.z.string().refine(isTimeZone, "an IANA time zone such as Europe/London").optional()
484
+ });
471
485
  IdentitySchema = import_zod.z.strictObject({
472
486
  $schema: import_zod.z.string().optional(),
473
487
  name: import_zod.z.string().min(1).regex(/^[A-Za-z0-9][A-Za-z0-9._@-]*$/),
474
488
  defaultConfigProfile: import_zod.z.string().min(1).optional(),
475
489
  allowAmbientCredential: import_zod.z.boolean().default(false),
476
- credential: CredentialSchema.optional()
490
+ credential: CredentialSchema.optional(),
491
+ /** When this identity's five-hour window should be open: the front door opens one at each anchor if none is. Absent, nothing is opened on a schedule. */
492
+ anchors: import_zod.z.array(AnchorSchema).min(1).optional()
477
493
  });
478
494
  CategoryClassificationSchema = import_zod.z.strictObject({
479
495
  $schema: import_zod.z.string().optional(),
@@ -2663,7 +2679,7 @@ var init_package = __esm({
2663
2679
  "package.json"() {
2664
2680
  package_default = {
2665
2681
  name: "claude-use",
2666
- version: "9.13.0",
2682
+ version: "9.14.0",
2667
2683
  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.",
2668
2684
  license: "MIT",
2669
2685
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -5307,6 +5323,7 @@ function buildLayoutPaths(root) {
5307
5323
  usageLogDir: import_node_path22.default.join(root, "usage", "log"),
5308
5324
  usageSnapshotsDir: import_node_path22.default.join(root, "usage", "snapshots"),
5309
5325
  usagePicksFile: import_node_path22.default.join(root, "usage", "picks.json"),
5326
+ usageAnchorsFile: import_node_path22.default.join(root, "usage", "anchors.json"),
5310
5327
  mcpPermissionsFile: import_node_path22.default.join(root, "mcp", "permissions.json")
5311
5328
  };
5312
5329
  }
@@ -7809,6 +7826,57 @@ var init_anthropicUsageRefresh = __esm({
7809
7826
  }
7810
7827
  });
7811
7828
 
7829
+ // src/usage/identityClaude.ts
7830
+ function definedEnvironment(env) {
7831
+ return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7832
+ }
7833
+ function identityLaunchArgv(identity, flags) {
7834
+ return [`@${identity}`, IDENTITY_ONLY_FLAG, ...flags];
7835
+ }
7836
+ async function withIdentityClaude(params, identity, flags, use) {
7837
+ const refusals = [];
7838
+ const plan = prepareLaunch(
7839
+ realPrepareLaunchParams(params.paths, {
7840
+ proc: {
7841
+ env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7842
+ argv: [...identityLaunchArgv(identity, flags)],
7843
+ exit: (code) => {
7844
+ throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7845
+ }
7846
+ },
7847
+ log: {
7848
+ info: () => void 0,
7849
+ warn: () => void 0,
7850
+ error: (message) => {
7851
+ refusals.push(message);
7852
+ }
7853
+ },
7854
+ spawnDaemon: params.spawnDaemon,
7855
+ farm: buildFarmRuntime(params.paths, params.cwd)
7856
+ })
7857
+ );
7858
+ const abort = new AbortController();
7859
+ const timer = setTimeout(() => {
7860
+ abort.abort();
7861
+ }, params.timeoutMs);
7862
+ try {
7863
+ return await use({ bin: plan.bin, env: definedEnvironment(plan.env), cwd: params.cwd, abort });
7864
+ } finally {
7865
+ clearTimeout(timer);
7866
+ plan.release();
7867
+ }
7868
+ }
7869
+ var CONFIG_DIR_VARIABLE, IDENTITY_ONLY_FLAG;
7870
+ var init_identityClaude = __esm({
7871
+ "src/usage/identityClaude.ts"() {
7872
+ "use strict";
7873
+ init_launchWiring();
7874
+ init_launcher();
7875
+ CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7876
+ IDENTITY_ONLY_FLAG = "--no-provider";
7877
+ }
7878
+ });
7879
+
7812
7880
  // src/usage/providerQuota.ts
7813
7881
  var import_zod25, MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY4, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
7814
7882
  var init_providerQuota = __esm({
@@ -7879,9 +7947,6 @@ var realAnthropicUsageProbe_exports = {};
7879
7947
  __export(realAnthropicUsageProbe_exports, {
7880
7948
  createRealAnthropicUsageRefresher: () => createRealAnthropicUsageRefresher
7881
7949
  });
7882
- function definedEnvironment(env) {
7883
- return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7884
- }
7885
7950
  function idlePrompt(signal) {
7886
7951
  return {
7887
7952
  [Symbol.asyncIterator]: () => ({
@@ -7894,58 +7959,28 @@ function idlePrompt(signal) {
7894
7959
  };
7895
7960
  }
7896
7961
  function createRealAnthropicUsageProbe(params) {
7897
- return async (identity) => {
7898
- const refusals = [];
7899
- const plan = prepareLaunch(
7900
- realPrepareLaunchParams(params.paths, {
7901
- proc: {
7902
- env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7903
- argv: [`@${identity}`, ...PROBE_LAUNCH_FLAGS],
7904
- exit: (code) => {
7905
- throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7906
- }
7907
- },
7908
- log: {
7909
- info: () => void 0,
7910
- warn: () => void 0,
7911
- error: (message) => {
7912
- refusals.push(message);
7913
- }
7914
- },
7915
- spawnDaemon: params.spawnDaemon,
7916
- farm: buildFarmRuntime(params.paths, params.cwd)
7917
- })
7918
- );
7962
+ return async (identity) => await withIdentityClaude(params, identity, PROBE_LAUNCH_FLAGS, async ({ bin, env, cwd, abort }) => {
7919
7963
  const { query } = await import("@anthropic-ai/claude-agent-sdk");
7920
- const abort = new AbortController();
7921
- const timer = setTimeout(() => {
7922
- abort.abort();
7923
- }, params.timeoutMs);
7924
- try {
7925
- const session = query({
7926
- prompt: idlePrompt(abort.signal),
7927
- options: {
7928
- pathToClaudeCodeExecutable: plan.bin,
7929
- env: definedEnvironment(plan.env),
7930
- cwd: params.cwd,
7931
- abortController: abort,
7932
- settingSources: [],
7933
- mcpServers: {},
7934
- strictMcpConfig: true,
7935
- persistSession: false
7936
- }
7937
- });
7938
- try {
7939
- const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7940
- return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7941
- } finally {
7942
- session.close();
7964
+ const session = query({
7965
+ prompt: idlePrompt(abort.signal),
7966
+ options: {
7967
+ pathToClaudeCodeExecutable: bin,
7968
+ env,
7969
+ cwd,
7970
+ abortController: abort,
7971
+ settingSources: [],
7972
+ mcpServers: {},
7973
+ strictMcpConfig: true,
7974
+ persistSession: false
7943
7975
  }
7976
+ });
7977
+ try {
7978
+ const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7979
+ return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7944
7980
  } finally {
7945
- clearTimeout(timer);
7946
- plan.release();
7981
+ session.close();
7947
7982
  }
7948
- };
7983
+ });
7949
7984
  }
7950
7985
  function createRealAnthropicUsageRefresher(params) {
7951
7986
  return createAnthropicUsageRefresher({
@@ -7958,18 +7993,16 @@ function createRealAnthropicUsageRefresher(params) {
7958
7993
  concurrency: (0, import_node_os8.availableParallelism)()
7959
7994
  });
7960
7995
  }
7961
- var import_node_os8, PROBE_LAUNCH_FLAGS, CONFIG_DIR_VARIABLE;
7996
+ var import_node_os8, PROBE_LAUNCH_FLAGS;
7962
7997
  var init_realAnthropicUsageProbe = __esm({
7963
7998
  "src/usage/realAnthropicUsageProbe.ts"() {
7964
7999
  "use strict";
7965
8000
  import_node_os8 = require("node:os");
7966
- init_launchWiring();
7967
- init_launcher();
7968
8001
  init_anthropicUsageRefresh();
8002
+ init_identityClaude();
7969
8003
  init_middleware();
7970
8004
  init_quotaRefresh();
7971
8005
  PROBE_LAUNCH_FLAGS = ["--no-headroom", "--no-remote-control"];
7972
- CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7973
8006
  }
7974
8007
  });
7975
8008
 
@@ -12789,6 +12822,12 @@ function listIdentities(paths) {
12789
12822
  }
12790
12823
  return result;
12791
12824
  }
12825
+ function setIdentityAnchors(paths, identityName, anchors) {
12826
+ if (!identityExists(paths, identityName)) {
12827
+ throw new IdentityNotFoundError(identityName);
12828
+ }
12829
+ return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { anchors: anchors === void 0 ? void 0 : [...anchors] });
12830
+ }
12792
12831
  function setDefaultConfigProfile(paths, identityName, profileName) {
12793
12832
  if (!identityExists(paths, identityName)) {
12794
12833
  throw new IdentityNotFoundError(identityName);
@@ -13893,7 +13932,8 @@ var IdentityValueSchema = import_zod22.z.strictObject({
13893
13932
  name: import_zod22.z.string(),
13894
13933
  defaultConfigProfile: import_zod22.z.string().optional(),
13895
13934
  allowAmbientCredential: import_zod22.z.boolean(),
13896
- credential: CredentialSummarySchema2.optional()
13935
+ credential: CredentialSummarySchema2.optional(),
13936
+ anchors: import_zod22.z.array(AnchorSchema).optional()
13897
13937
  });
13898
13938
  var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
13899
13939
  var ProviderValueSchema = import_zod22.z.strictObject({
@@ -13911,7 +13951,9 @@ var ConfigIdentitySetInputSchema = import_zod22.z.strictObject({
13911
13951
  name: import_zod22.z.string().min(1),
13912
13952
  defaultConfigProfile: import_zod22.z.union([import_zod22.z.string().min(1), import_zod22.z.literal(false)]).optional(),
13913
13953
  allowAmbientCredential: import_zod22.z.boolean().optional(),
13914
- credential: import_zod22.z.union([import_zod22.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
13954
+ credential: import_zod22.z.union([import_zod22.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
13955
+ /** `false` removes the anchors; a list replaces them. */
13956
+ anchors: import_zod22.z.union([import_zod22.z.literal(false), import_zod22.z.array(AnchorSchema).min(1)]).optional()
13915
13957
  });
13916
13958
  var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
13917
13959
  var ConfigIdentityRemoveInputSchema = import_zod22.z.strictObject({ name: import_zod22.z.string().min(1), confirm: RemovalConfirmationSchema });
@@ -14032,7 +14074,8 @@ function identityValue(name, paths) {
14032
14074
  name: identity.name,
14033
14075
  ...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
14034
14076
  allowAmbientCredential: identity.allowAmbientCredential,
14035
- ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
14077
+ ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) },
14078
+ ...identity.anchors === void 0 ? {} : { anchors: identity.anchors }
14036
14079
  };
14037
14080
  }
14038
14081
  function providerValue(name, provider) {
@@ -14063,9 +14106,9 @@ function createConfigApiRouter(deps) {
14063
14106
  return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
14064
14107
  })
14065
14108
  ),
14066
- set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
14109
+ set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
14067
14110
  ({ input }) => guarded(() => {
14068
- requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
14111
+ requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0 || input.anchors !== void 0, "defaultConfigProfile, allowAmbientCredential, credential or anchors");
14069
14112
  if (!identityExists(paths, input.name)) {
14070
14113
  throw new IdentityNotFoundError(input.name);
14071
14114
  }
@@ -14090,6 +14133,9 @@ function createConfigApiRouter(deps) {
14090
14133
  };
14091
14134
  setIdentityCredential(paths, input.name, change);
14092
14135
  }
14136
+ if (input.anchors !== void 0) {
14137
+ setIdentityAnchors(paths, input.name, input.anchors === false ? void 0 : input.anchors);
14138
+ }
14093
14139
  return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
14094
14140
  })
14095
14141
  ),
package/dist/index.mjs CHANGED
@@ -209,7 +209,15 @@ function isCodexProvider(provider) {
209
209
  function poolMemberIdentity(member) {
210
210
  return typeof member === "string" ? member : member.identity;
211
211
  }
212
- 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, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, 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;
212
+ function isTimeZone(name) {
213
+ try {
214
+ new Intl.DateTimeFormat("en", { timeZone: name });
215
+ return true;
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+ 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, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, 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, WEEKDAYS, AnchorSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
213
221
  var init_schema = __esm({
214
222
  "src/config/schema.ts"() {
215
223
  "use strict";
@@ -446,12 +454,20 @@ var init_schema = __esm({
446
454
  update: UpdateGlobalConfigSchema.optional(),
447
455
  pools: z.record(PoolNameSchema, PoolSchema).optional()
448
456
  });
457
+ WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
458
+ AnchorSchema = z.strictObject({
459
+ days: z.array(z.enum(WEEKDAYS)).min(1).refine((days) => new Set(days).size === days.length, "an anchor names each weekday at most once"),
460
+ time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a 24-hour time such as 06:00"),
461
+ timeZone: z.string().refine(isTimeZone, "an IANA time zone such as Europe/London").optional()
462
+ });
449
463
  IdentitySchema = z.strictObject({
450
464
  $schema: z.string().optional(),
451
465
  name: z.string().min(1).regex(/^[A-Za-z0-9][A-Za-z0-9._@-]*$/),
452
466
  defaultConfigProfile: z.string().min(1).optional(),
453
467
  allowAmbientCredential: z.boolean().default(false),
454
- credential: CredentialSchema.optional()
468
+ credential: CredentialSchema.optional(),
469
+ /** When this identity's five-hour window should be open: the front door opens one at each anchor if none is. Absent, nothing is opened on a schedule. */
470
+ anchors: z.array(AnchorSchema).min(1).optional()
455
471
  });
456
472
  CategoryClassificationSchema = z.strictObject({
457
473
  $schema: z.string().optional(),
@@ -2639,7 +2655,7 @@ var init_package = __esm({
2639
2655
  "package.json"() {
2640
2656
  package_default = {
2641
2657
  name: "claude-use",
2642
- version: "9.13.0",
2658
+ version: "9.14.0",
2643
2659
  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.",
2644
2660
  license: "MIT",
2645
2661
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -5284,6 +5300,7 @@ function buildLayoutPaths(root) {
5284
5300
  usageLogDir: path22.join(root, "usage", "log"),
5285
5301
  usageSnapshotsDir: path22.join(root, "usage", "snapshots"),
5286
5302
  usagePicksFile: path22.join(root, "usage", "picks.json"),
5303
+ usageAnchorsFile: path22.join(root, "usage", "anchors.json"),
5287
5304
  mcpPermissionsFile: path22.join(root, "mcp", "permissions.json")
5288
5305
  };
5289
5306
  }
@@ -7781,6 +7798,57 @@ var init_anthropicUsageRefresh = __esm({
7781
7798
  }
7782
7799
  });
7783
7800
 
7801
+ // src/usage/identityClaude.ts
7802
+ function definedEnvironment(env) {
7803
+ return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7804
+ }
7805
+ function identityLaunchArgv(identity, flags) {
7806
+ return [`@${identity}`, IDENTITY_ONLY_FLAG, ...flags];
7807
+ }
7808
+ async function withIdentityClaude(params, identity, flags, use) {
7809
+ const refusals = [];
7810
+ const plan = prepareLaunch(
7811
+ realPrepareLaunchParams(params.paths, {
7812
+ proc: {
7813
+ env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7814
+ argv: [...identityLaunchArgv(identity, flags)],
7815
+ exit: (code) => {
7816
+ throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7817
+ }
7818
+ },
7819
+ log: {
7820
+ info: () => void 0,
7821
+ warn: () => void 0,
7822
+ error: (message) => {
7823
+ refusals.push(message);
7824
+ }
7825
+ },
7826
+ spawnDaemon: params.spawnDaemon,
7827
+ farm: buildFarmRuntime(params.paths, params.cwd)
7828
+ })
7829
+ );
7830
+ const abort = new AbortController();
7831
+ const timer = setTimeout(() => {
7832
+ abort.abort();
7833
+ }, params.timeoutMs);
7834
+ try {
7835
+ return await use({ bin: plan.bin, env: definedEnvironment(plan.env), cwd: params.cwd, abort });
7836
+ } finally {
7837
+ clearTimeout(timer);
7838
+ plan.release();
7839
+ }
7840
+ }
7841
+ var CONFIG_DIR_VARIABLE, IDENTITY_ONLY_FLAG;
7842
+ var init_identityClaude = __esm({
7843
+ "src/usage/identityClaude.ts"() {
7844
+ "use strict";
7845
+ init_launchWiring();
7846
+ init_launcher();
7847
+ CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7848
+ IDENTITY_ONLY_FLAG = "--no-provider";
7849
+ }
7850
+ });
7851
+
7784
7852
  // src/usage/providerQuota.ts
7785
7853
  import { z as z25 } from "zod";
7786
7854
  var MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY4, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
@@ -7852,9 +7920,6 @@ __export(realAnthropicUsageProbe_exports, {
7852
7920
  createRealAnthropicUsageRefresher: () => createRealAnthropicUsageRefresher
7853
7921
  });
7854
7922
  import { availableParallelism } from "node:os";
7855
- function definedEnvironment(env) {
7856
- return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7857
- }
7858
7923
  function idlePrompt(signal) {
7859
7924
  return {
7860
7925
  [Symbol.asyncIterator]: () => ({
@@ -7867,58 +7932,28 @@ function idlePrompt(signal) {
7867
7932
  };
7868
7933
  }
7869
7934
  function createRealAnthropicUsageProbe(params) {
7870
- return async (identity) => {
7871
- const refusals = [];
7872
- const plan = prepareLaunch(
7873
- realPrepareLaunchParams(params.paths, {
7874
- proc: {
7875
- env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7876
- argv: [`@${identity}`, ...PROBE_LAUNCH_FLAGS],
7877
- exit: (code) => {
7878
- throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7879
- }
7880
- },
7881
- log: {
7882
- info: () => void 0,
7883
- warn: () => void 0,
7884
- error: (message) => {
7885
- refusals.push(message);
7886
- }
7887
- },
7888
- spawnDaemon: params.spawnDaemon,
7889
- farm: buildFarmRuntime(params.paths, params.cwd)
7890
- })
7891
- );
7935
+ return async (identity) => await withIdentityClaude(params, identity, PROBE_LAUNCH_FLAGS, async ({ bin, env, cwd, abort }) => {
7892
7936
  const { query } = await import("@anthropic-ai/claude-agent-sdk");
7893
- const abort = new AbortController();
7894
- const timer = setTimeout(() => {
7895
- abort.abort();
7896
- }, params.timeoutMs);
7897
- try {
7898
- const session = query({
7899
- prompt: idlePrompt(abort.signal),
7900
- options: {
7901
- pathToClaudeCodeExecutable: plan.bin,
7902
- env: definedEnvironment(plan.env),
7903
- cwd: params.cwd,
7904
- abortController: abort,
7905
- settingSources: [],
7906
- mcpServers: {},
7907
- strictMcpConfig: true,
7908
- persistSession: false
7909
- }
7910
- });
7911
- try {
7912
- const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7913
- return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7914
- } finally {
7915
- session.close();
7937
+ const session = query({
7938
+ prompt: idlePrompt(abort.signal),
7939
+ options: {
7940
+ pathToClaudeCodeExecutable: bin,
7941
+ env,
7942
+ cwd,
7943
+ abortController: abort,
7944
+ settingSources: [],
7945
+ mcpServers: {},
7946
+ strictMcpConfig: true,
7947
+ persistSession: false
7916
7948
  }
7949
+ });
7950
+ try {
7951
+ const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7952
+ return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7917
7953
  } finally {
7918
- clearTimeout(timer);
7919
- plan.release();
7954
+ session.close();
7920
7955
  }
7921
- };
7956
+ });
7922
7957
  }
7923
7958
  function createRealAnthropicUsageRefresher(params) {
7924
7959
  return createAnthropicUsageRefresher({
@@ -7931,17 +7966,15 @@ function createRealAnthropicUsageRefresher(params) {
7931
7966
  concurrency: availableParallelism()
7932
7967
  });
7933
7968
  }
7934
- var PROBE_LAUNCH_FLAGS, CONFIG_DIR_VARIABLE;
7969
+ var PROBE_LAUNCH_FLAGS;
7935
7970
  var init_realAnthropicUsageProbe = __esm({
7936
7971
  "src/usage/realAnthropicUsageProbe.ts"() {
7937
7972
  "use strict";
7938
- init_launchWiring();
7939
- init_launcher();
7940
7973
  init_anthropicUsageRefresh();
7974
+ init_identityClaude();
7941
7975
  init_middleware();
7942
7976
  init_quotaRefresh();
7943
7977
  PROBE_LAUNCH_FLAGS = ["--no-headroom", "--no-remote-control"];
7944
- CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7945
7978
  }
7946
7979
  });
7947
7980
 
@@ -12404,6 +12437,12 @@ function listIdentities(paths) {
12404
12437
  }
12405
12438
  return result;
12406
12439
  }
12440
+ function setIdentityAnchors(paths, identityName, anchors) {
12441
+ if (!identityExists(paths, identityName)) {
12442
+ throw new IdentityNotFoundError(identityName);
12443
+ }
12444
+ return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { anchors: anchors === void 0 ? void 0 : [...anchors] });
12445
+ }
12407
12446
  function setDefaultConfigProfile(paths, identityName, profileName) {
12408
12447
  if (!identityExists(paths, identityName)) {
12409
12448
  throw new IdentityNotFoundError(identityName);
@@ -13508,7 +13547,8 @@ var IdentityValueSchema = z22.strictObject({
13508
13547
  name: z22.string(),
13509
13548
  defaultConfigProfile: z22.string().optional(),
13510
13549
  allowAmbientCredential: z22.boolean(),
13511
- credential: CredentialSummarySchema2.optional()
13550
+ credential: CredentialSummarySchema2.optional(),
13551
+ anchors: z22.array(AnchorSchema).optional()
13512
13552
  });
13513
13553
  var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
13514
13554
  var ProviderValueSchema = z22.strictObject({
@@ -13526,7 +13566,9 @@ var ConfigIdentitySetInputSchema = z22.strictObject({
13526
13566
  name: z22.string().min(1),
13527
13567
  defaultConfigProfile: z22.union([z22.string().min(1), z22.literal(false)]).optional(),
13528
13568
  allowAmbientCredential: z22.boolean().optional(),
13529
- credential: z22.union([z22.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
13569
+ credential: z22.union([z22.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
13570
+ /** `false` removes the anchors; a list replaces them. */
13571
+ anchors: z22.union([z22.literal(false), z22.array(AnchorSchema).min(1)]).optional()
13530
13572
  });
13531
13573
  var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
13532
13574
  var ConfigIdentityRemoveInputSchema = z22.strictObject({ name: z22.string().min(1), confirm: RemovalConfirmationSchema });
@@ -13647,7 +13689,8 @@ function identityValue(name, paths) {
13647
13689
  name: identity.name,
13648
13690
  ...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
13649
13691
  allowAmbientCredential: identity.allowAmbientCredential,
13650
- ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
13692
+ ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) },
13693
+ ...identity.anchors === void 0 ? {} : { anchors: identity.anchors }
13651
13694
  };
13652
13695
  }
13653
13696
  function providerValue(name, provider) {
@@ -13678,9 +13721,9 @@ function createConfigApiRouter(deps) {
13678
13721
  return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13679
13722
  })
13680
13723
  ),
13681
- set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
13724
+ set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
13682
13725
  ({ input }) => guarded(() => {
13683
- requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
13726
+ requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0 || input.anchors !== void 0, "defaultConfigProfile, allowAmbientCredential, credential or anchors");
13684
13727
  if (!identityExists(paths, input.name)) {
13685
13728
  throw new IdentityNotFoundError(input.name);
13686
13729
  }
@@ -13705,6 +13748,9 @@ function createConfigApiRouter(deps) {
13705
13748
  };
13706
13749
  setIdentityCredential(paths, input.name, change);
13707
13750
  }
13751
+ if (input.anchors !== void 0) {
13752
+ setIdentityAnchors(paths, input.name, input.anchors === false ? void 0 : input.anchors);
13753
+ }
13708
13754
  return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13709
13755
  })
13710
13756
  ),