agent-shim 11.77.0 → 11.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -38198,7 +38198,7 @@ var init_package = __esm({
38198
38198
  "package.json"() {
38199
38199
  package_default = {
38200
38200
  name: "agent-shim",
38201
- version: "11.77.0",
38201
+ version: "11.78.0",
38202
38202
  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.",
38203
38203
  license: "MIT",
38204
38204
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -117743,7 +117743,7 @@ function summariseIdentityAccount(account) {
117743
117743
  function loginKeyOf(account) {
117744
117744
  return account.accountUuid === void 0 ? void 0 : JSON.stringify([account.accountUuid, account.organizationUuid ?? null]);
117745
117745
  }
117746
- function groupByLogin(items, loginOf) {
117746
+ function collectByLogin(items, loginOf) {
117747
117747
  const groups = /* @__PURE__ */ new Map();
117748
117748
  for (const item of items) {
117749
117749
  const key = loginOf(item) ?? /* @__PURE__ */ Symbol("no login");
@@ -117754,7 +117754,13 @@ function groupByLogin(items, loginOf) {
117754
117754
  group.push(item);
117755
117755
  }
117756
117756
  }
117757
- return [...groups.values()].flat();
117757
+ return [...groups.values()];
117758
+ }
117759
+ function groupByLogin(items, loginOf) {
117760
+ return collectByLogin(items, loginOf).flat();
117761
+ }
117762
+ function groupSharedLogins(items, loginOf) {
117763
+ return collectByLogin(items, loginOf).filter((group) => group.length > 1);
117758
117764
  }
117759
117765
  function describeAccountHolder(summary) {
117760
117766
  const organisation = describeAccountOrganisation(summary);
@@ -123523,6 +123529,10 @@ var DOCTOR_SECTIONS = [
123523
123529
  "frontdoor",
123524
123530
  "models"
123525
123531
  ];
123532
+ function joinNames(names) {
123533
+ const last = names.at(-1);
123534
+ return names.length < 2 || last === void 0 ? names.join("") : `${names.slice(0, -1).join(", ")} and ${last}`;
123535
+ }
123526
123536
  function refinePathShadow(status, ownExecutablePath, realpath) {
123527
123537
  if (status.status !== "shadowed") {
123528
123538
  return status;
@@ -123770,6 +123780,7 @@ function runDoctor(params) {
123770
123780
  const validProfileNames = new Set(profileSources.keys());
123771
123781
  const validProviderNames = /* @__PURE__ */ new Set([...params.providers.map((entry) => entry.name), ...Object.keys(params.providerAliases ?? {})]);
123772
123782
  const validIdentityNames = /* @__PURE__ */ new Set();
123783
+ const signedInAccounts = [];
123773
123784
  for (const entry of params.identities) {
123774
123785
  const validated2 = validate3(IdentitySchema, entry, "identity", entry.name);
123775
123786
  if (!validated2.ok) {
@@ -123819,6 +123830,18 @@ function runDoctor(params) {
123819
123830
  signIn.state === "signed-out" ? `${entry.name} is signed out (${signIn.detail}). Run \`agent-shim run @${entry.name}\` and sign in.` : `${entry.name} ${standing} (${signIn.detail}).`,
123820
123831
  entry.name
123821
123832
  );
123833
+ if (signIn.state === "signed-in" && entry.account !== void 0) {
123834
+ signedInAccounts.push({ name: entry.name, account: entry.account });
123835
+ }
123836
+ }
123837
+ for (const group of groupSharedLogins(signedInAccounts, (entry) => loginKeyOf(entry.account))) {
123838
+ const names = group.map((entry) => entry.name);
123839
+ const holder = group.map((entry) => summariseIdentityAccount(entry.account)).map((summary) => summary === void 0 ? void 0 : describeAccountHolder(summary)).find((described) => described !== void 0);
123840
+ push(
123841
+ "sign-in",
123842
+ "warn",
123843
+ `Identities ${joinNames(names)} hold the same login${holder === void 0 ? "" : ` (${holder})`}, so they share one quota window and all but one are redundant. Remove the redundant ones with \`agent-shim identity remove <name>\`.`
123844
+ );
123822
123845
  }
123823
123846
  const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
123824
123847
  const pools = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.pools ?? {} : {};
@@ -124107,7 +124130,7 @@ function collectDoctorReport(params) {
124107
124130
  const identities = identityNames.map((name) => {
124108
124131
  const farmRoot = import_node_path47.default.join(paths.identitiesDir, name);
124109
124132
  const identityPath = import_node_path47.default.join(farmRoot, "identity.json");
124110
- return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: import_node_fs20.default.existsSync(credentialsFilePath(farmRoot)) };
124133
+ return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: import_node_fs20.default.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, name)?.account };
124111
124134
  });
124112
124135
  const profileNames = import_node_fs20.default.existsSync(paths.configProfilesDir) ? import_node_fs20.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
124113
124136
  const configProfiles = profileNames.map((name) => {
package/dist/index.cjs CHANGED
@@ -4764,7 +4764,7 @@ var init_package = __esm({
4764
4764
  "package.json"() {
4765
4765
  package_default = {
4766
4766
  name: "agent-shim",
4767
- version: "11.77.0",
4767
+ version: "11.78.0",
4768
4768
  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.",
4769
4769
  license: "MIT",
4770
4770
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -17084,6 +17084,65 @@ var import_node_fs10 = __toESM(require("node:fs"), 1);
17084
17084
  var import_node_path29 = __toESM(require("node:path"), 1);
17085
17085
  init_signIn();
17086
17086
 
17087
+ // src/identityAccounts.ts
17088
+ init_account();
17089
+
17090
+ // src/usage/accountDescription.ts
17091
+ function describeAccountOrganisation(account) {
17092
+ const parts = [account.organizationName, account.organizationType].filter((part) => part !== void 0);
17093
+ return parts.length === 0 ? void 0 : parts.join(", ");
17094
+ }
17095
+
17096
+ // src/identityAccounts.ts
17097
+ function readIdentityAccount(fs14, identitiesDir, identity) {
17098
+ try {
17099
+ const account = readAccountMetadata(fs14, identitiesDir, identity);
17100
+ return account === void 0 ? void 0 : { account };
17101
+ } catch (error) {
17102
+ if (error instanceof AccountMetadataError) {
17103
+ return { problem: error.message };
17104
+ }
17105
+ throw error;
17106
+ }
17107
+ }
17108
+ function summariseIdentityAccount(account) {
17109
+ const summary = {
17110
+ ...account.emailAddress === void 0 ? {} : { emailAddress: account.emailAddress },
17111
+ ...account.organizationName === void 0 ? {} : { organizationName: account.organizationName },
17112
+ ...account.organizationType === void 0 ? {} : { organizationType: account.organizationType },
17113
+ ...account.organizationRole === void 0 ? {} : { organizationRole: account.organizationRole },
17114
+ ...account.billingType === void 0 ? {} : { billingType: account.billingType },
17115
+ ...account.seatTier === void 0 ? {} : { seatTier: account.seatTier }
17116
+ };
17117
+ return Object.keys(summary).length === 0 ? void 0 : summary;
17118
+ }
17119
+ function loginKeyOf(account) {
17120
+ return account.accountUuid === void 0 ? void 0 : JSON.stringify([account.accountUuid, account.organizationUuid ?? null]);
17121
+ }
17122
+ function collectByLogin(items, loginOf) {
17123
+ const groups = /* @__PURE__ */ new Map();
17124
+ for (const item of items) {
17125
+ const key = loginOf(item) ?? /* @__PURE__ */ Symbol("no login");
17126
+ const group = groups.get(key);
17127
+ if (group === void 0) {
17128
+ groups.set(key, [item]);
17129
+ } else {
17130
+ group.push(item);
17131
+ }
17132
+ }
17133
+ return [...groups.values()];
17134
+ }
17135
+ function groupSharedLogins(items, loginOf) {
17136
+ return collectByLogin(items, loginOf).filter((group) => group.length > 1);
17137
+ }
17138
+ function describeAccountHolder(summary) {
17139
+ const organisation = describeAccountOrganisation(summary);
17140
+ if (summary.emailAddress === void 0) {
17141
+ return organisation;
17142
+ }
17143
+ return organisation === void 0 ? summary.emailAddress : `${summary.emailAddress} (${organisation})`;
17144
+ }
17145
+
17087
17146
  // src/codex/siwcStore.ts
17088
17147
  var import_zod26 = require("zod");
17089
17148
 
@@ -17458,6 +17517,10 @@ var DOCTOR_SECTIONS = [
17458
17517
  "frontdoor",
17459
17518
  "models"
17460
17519
  ];
17520
+ function joinNames(names) {
17521
+ const last = names.at(-1);
17522
+ return names.length < 2 || last === void 0 ? names.join("") : `${names.slice(0, -1).join(", ")} and ${last}`;
17523
+ }
17461
17524
  function refinePathShadow(status, ownExecutablePath, realpath) {
17462
17525
  if (status.status !== "shadowed") {
17463
17526
  return status;
@@ -17705,6 +17768,7 @@ function runDoctor(params) {
17705
17768
  const validProfileNames = new Set(profileSources.keys());
17706
17769
  const validProviderNames = /* @__PURE__ */ new Set([...params.providers.map((entry) => entry.name), ...Object.keys(params.providerAliases ?? {})]);
17707
17770
  const validIdentityNames = /* @__PURE__ */ new Set();
17771
+ const signedInAccounts = [];
17708
17772
  for (const entry of params.identities) {
17709
17773
  const validated3 = validate(IdentitySchema, entry, "identity", entry.name);
17710
17774
  if (!validated3.ok) {
@@ -17754,6 +17818,18 @@ function runDoctor(params) {
17754
17818
  signIn.state === "signed-out" ? `${entry.name} is signed out (${signIn.detail}). Run \`agent-shim run @${entry.name}\` and sign in.` : `${entry.name} ${standing} (${signIn.detail}).`,
17755
17819
  entry.name
17756
17820
  );
17821
+ if (signIn.state === "signed-in" && entry.account !== void 0) {
17822
+ signedInAccounts.push({ name: entry.name, account: entry.account });
17823
+ }
17824
+ }
17825
+ for (const group of groupSharedLogins(signedInAccounts, (entry) => loginKeyOf(entry.account))) {
17826
+ const names = group.map((entry) => entry.name);
17827
+ const holder = group.map((entry) => summariseIdentityAccount(entry.account)).map((summary) => summary === void 0 ? void 0 : describeAccountHolder(summary)).find((described) => described !== void 0);
17828
+ push(
17829
+ "sign-in",
17830
+ "warn",
17831
+ `Identities ${joinNames(names)} hold the same login${holder === void 0 ? "" : ` (${holder})`}, so they share one quota window and all but one are redundant. Remove the redundant ones with \`agent-shim identity remove <name>\`.`
17832
+ );
17757
17833
  }
17758
17834
  const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
17759
17835
  const pools = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.pools ?? {} : {};
@@ -18042,7 +18118,7 @@ function collectDoctorReport(params) {
18042
18118
  const identities = identityNames.map((name) => {
18043
18119
  const farmRoot = import_node_path29.default.join(paths.identitiesDir, name);
18044
18120
  const identityPath = import_node_path29.default.join(farmRoot, "identity.json");
18045
- return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: import_node_fs10.default.existsSync(credentialsFilePath(farmRoot)) };
18121
+ return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: import_node_fs10.default.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, name)?.account };
18046
18122
  });
18047
18123
  const profileNames = import_node_fs10.default.existsSync(paths.configProfilesDir) ? import_node_fs10.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
18048
18124
  const configProfiles = profileNames.map((name) => {
package/dist/index.mjs CHANGED
@@ -4740,7 +4740,7 @@ var init_package = __esm({
4740
4740
  "package.json"() {
4741
4741
  package_default = {
4742
4742
  name: "agent-shim",
4743
- version: "11.77.0",
4743
+ version: "11.78.0",
4744
4744
  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.",
4745
4745
  license: "MIT",
4746
4746
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -16669,6 +16669,65 @@ import fs11 from "node:fs";
16669
16669
  import path29 from "node:path";
16670
16670
  init_signIn();
16671
16671
 
16672
+ // src/identityAccounts.ts
16673
+ init_account();
16674
+
16675
+ // src/usage/accountDescription.ts
16676
+ function describeAccountOrganisation(account) {
16677
+ const parts = [account.organizationName, account.organizationType].filter((part) => part !== void 0);
16678
+ return parts.length === 0 ? void 0 : parts.join(", ");
16679
+ }
16680
+
16681
+ // src/identityAccounts.ts
16682
+ function readIdentityAccount(fs14, identitiesDir, identity) {
16683
+ try {
16684
+ const account = readAccountMetadata(fs14, identitiesDir, identity);
16685
+ return account === void 0 ? void 0 : { account };
16686
+ } catch (error) {
16687
+ if (error instanceof AccountMetadataError) {
16688
+ return { problem: error.message };
16689
+ }
16690
+ throw error;
16691
+ }
16692
+ }
16693
+ function summariseIdentityAccount(account) {
16694
+ const summary = {
16695
+ ...account.emailAddress === void 0 ? {} : { emailAddress: account.emailAddress },
16696
+ ...account.organizationName === void 0 ? {} : { organizationName: account.organizationName },
16697
+ ...account.organizationType === void 0 ? {} : { organizationType: account.organizationType },
16698
+ ...account.organizationRole === void 0 ? {} : { organizationRole: account.organizationRole },
16699
+ ...account.billingType === void 0 ? {} : { billingType: account.billingType },
16700
+ ...account.seatTier === void 0 ? {} : { seatTier: account.seatTier }
16701
+ };
16702
+ return Object.keys(summary).length === 0 ? void 0 : summary;
16703
+ }
16704
+ function loginKeyOf(account) {
16705
+ return account.accountUuid === void 0 ? void 0 : JSON.stringify([account.accountUuid, account.organizationUuid ?? null]);
16706
+ }
16707
+ function collectByLogin(items, loginOf) {
16708
+ const groups = /* @__PURE__ */ new Map();
16709
+ for (const item of items) {
16710
+ const key = loginOf(item) ?? /* @__PURE__ */ Symbol("no login");
16711
+ const group = groups.get(key);
16712
+ if (group === void 0) {
16713
+ groups.set(key, [item]);
16714
+ } else {
16715
+ group.push(item);
16716
+ }
16717
+ }
16718
+ return [...groups.values()];
16719
+ }
16720
+ function groupSharedLogins(items, loginOf) {
16721
+ return collectByLogin(items, loginOf).filter((group) => group.length > 1);
16722
+ }
16723
+ function describeAccountHolder(summary) {
16724
+ const organisation = describeAccountOrganisation(summary);
16725
+ if (summary.emailAddress === void 0) {
16726
+ return organisation;
16727
+ }
16728
+ return organisation === void 0 ? summary.emailAddress : `${summary.emailAddress} (${organisation})`;
16729
+ }
16730
+
16672
16731
  // src/codex/siwcStore.ts
16673
16732
  import { z as z26 } from "zod";
16674
16733
 
@@ -17043,6 +17102,10 @@ var DOCTOR_SECTIONS = [
17043
17102
  "frontdoor",
17044
17103
  "models"
17045
17104
  ];
17105
+ function joinNames(names) {
17106
+ const last = names.at(-1);
17107
+ return names.length < 2 || last === void 0 ? names.join("") : `${names.slice(0, -1).join(", ")} and ${last}`;
17108
+ }
17046
17109
  function refinePathShadow(status, ownExecutablePath, realpath) {
17047
17110
  if (status.status !== "shadowed") {
17048
17111
  return status;
@@ -17290,6 +17353,7 @@ function runDoctor(params) {
17290
17353
  const validProfileNames = new Set(profileSources.keys());
17291
17354
  const validProviderNames = /* @__PURE__ */ new Set([...params.providers.map((entry) => entry.name), ...Object.keys(params.providerAliases ?? {})]);
17292
17355
  const validIdentityNames = /* @__PURE__ */ new Set();
17356
+ const signedInAccounts = [];
17293
17357
  for (const entry of params.identities) {
17294
17358
  const validated3 = validate(IdentitySchema, entry, "identity", entry.name);
17295
17359
  if (!validated3.ok) {
@@ -17339,6 +17403,18 @@ function runDoctor(params) {
17339
17403
  signIn.state === "signed-out" ? `${entry.name} is signed out (${signIn.detail}). Run \`agent-shim run @${entry.name}\` and sign in.` : `${entry.name} ${standing} (${signIn.detail}).`,
17340
17404
  entry.name
17341
17405
  );
17406
+ if (signIn.state === "signed-in" && entry.account !== void 0) {
17407
+ signedInAccounts.push({ name: entry.name, account: entry.account });
17408
+ }
17409
+ }
17410
+ for (const group of groupSharedLogins(signedInAccounts, (entry) => loginKeyOf(entry.account))) {
17411
+ const names = group.map((entry) => entry.name);
17412
+ const holder = group.map((entry) => summariseIdentityAccount(entry.account)).map((summary) => summary === void 0 ? void 0 : describeAccountHolder(summary)).find((described) => described !== void 0);
17413
+ push(
17414
+ "sign-in",
17415
+ "warn",
17416
+ `Identities ${joinNames(names)} hold the same login${holder === void 0 ? "" : ` (${holder})`}, so they share one quota window and all but one are redundant. Remove the redundant ones with \`agent-shim identity remove <name>\`.`
17417
+ );
17342
17418
  }
17343
17419
  const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
17344
17420
  const pools = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.pools ?? {} : {};
@@ -17627,7 +17703,7 @@ function collectDoctorReport(params) {
17627
17703
  const identities = identityNames.map((name) => {
17628
17704
  const farmRoot = path29.join(paths.identitiesDir, name);
17629
17705
  const identityPath = path29.join(farmRoot, "identity.json");
17630
- return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: fs11.existsSync(credentialsFilePath(farmRoot)) };
17706
+ return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: fs11.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, name)?.account };
17631
17707
  });
17632
17708
  const profileNames = fs11.existsSync(paths.configProfilesDir) ? fs11.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
17633
17709
  const configProfiles = profileNames.map((name) => {
@@ -8876,6 +8876,180 @@ type PathShadowStatus = {
8876
8876
  readonly by: string;
8877
8877
  };
8878
8878
 
8879
+ /** One routed request, appended to the usage log when its response has finished. */
8880
+ declare const UsageRecordSchema: z.ZodObject<{
8881
+ schemaVersion: z.ZodLiteral<1>;
8882
+ at: z.ZodISODateTime;
8883
+ identity: z.ZodOptional<z.ZodString>;
8884
+ provider: z.ZodString;
8885
+ sessionId: z.ZodOptional<z.ZodString>;
8886
+ clientSessionId: z.ZodOptional<z.ZodString>;
8887
+ project: z.ZodOptional<z.ZodString>;
8888
+ viaHeadroom: z.ZodOptional<z.ZodBoolean>;
8889
+ route: z.ZodString;
8890
+ method: z.ZodString;
8891
+ endpoint: z.ZodString;
8892
+ model: z.ZodOptional<z.ZodString>;
8893
+ requestedModel: z.ZodOptional<z.ZodString>;
8894
+ candidateProviders: z.ZodOptional<z.ZodArray<z.ZodString>>;
8895
+ status: z.ZodNumber;
8896
+ latencyMs: z.ZodNumber;
8897
+ durationMs: z.ZodNumber;
8898
+ outcome: z.ZodEnum<{
8899
+ completed: "completed";
8900
+ aborted: "aborted";
8901
+ }>;
8902
+ usage: z.ZodOptional<z.ZodObject<{
8903
+ inputTokens: z.ZodOptional<z.ZodNumber>;
8904
+ outputTokens: z.ZodOptional<z.ZodNumber>;
8905
+ cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
8906
+ cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
8907
+ }, z.core.$strict>>;
8908
+ rateLimitHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
8909
+ limit: z.ZodOptional<z.ZodObject<{
8910
+ kind: z.ZodEnum<{
8911
+ "rate-limited": "rate-limited";
8912
+ "quota-exhausted": "quota-exhausted";
8913
+ }>;
8914
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
8915
+ resetAt: z.ZodOptional<z.ZodISODateTime>;
8916
+ window: z.ZodOptional<z.ZodString>;
8917
+ evidence: z.ZodArray<z.ZodString>;
8918
+ }, z.core.$strict>>;
8919
+ requestId: z.ZodOptional<z.ZodString>;
8920
+ }, z.core.$strict>;
8921
+ type UsageRecord = z.infer<typeof UsageRecordSchema>;
8922
+ /** One quota window from Anthropic's unified rate-limit headers. */
8923
+ declare const QuotaWindowSchema: z.ZodObject<{
8924
+ utilization: z.ZodOptional<z.ZodNumber>;
8925
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
8926
+ status: z.ZodOptional<z.ZodString>;
8927
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
8928
+ }, z.core.$strict>;
8929
+ type QuotaWindow = z.infer<typeof QuotaWindowSchema>;
8930
+ /**
8931
+ * The account fields copied from an identity's stored Claude login (`oauthAccount` in the identity's `.claude.json`): who the account is and which plan and tier it is on. Never the token, which Claude Code keeps elsewhere. Each field is present only when the stored login has it; a setup-token identity has no profile scope and so none of them (see issue #44).
8932
+ */
8933
+ declare const AccountMetadataSchema: z.ZodObject<{
8934
+ accountUuid: z.ZodOptional<z.ZodString>;
8935
+ emailAddress: z.ZodOptional<z.ZodString>;
8936
+ displayName: z.ZodOptional<z.ZodString>;
8937
+ organizationUuid: z.ZodOptional<z.ZodString>;
8938
+ organizationName: z.ZodOptional<z.ZodString>;
8939
+ organizationType: z.ZodOptional<z.ZodString>;
8940
+ organizationRole: z.ZodOptional<z.ZodString>;
8941
+ workspaceRole: z.ZodOptional<z.ZodString>;
8942
+ billingType: z.ZodOptional<z.ZodString>;
8943
+ seatTier: z.ZodOptional<z.ZodString>;
8944
+ organizationRateLimitTier: z.ZodOptional<z.ZodString>;
8945
+ userRateLimitTier: z.ZodOptional<z.ZodString>;
8946
+ hasExtraUsageEnabled: z.ZodOptional<z.ZodBoolean>;
8947
+ subscriptionCreatedAt: z.ZodOptional<z.ZodString>;
8948
+ accountCreatedAt: z.ZodOptional<z.ZodString>;
8949
+ }, z.core.$strict>;
8950
+ type AccountMetadata = z.infer<typeof AccountMetadataSchema>;
8951
+ /**
8952
+ * The latest state for one identity, rewritten atomically after each recorded response: the snapshot file other tools read (`~/.agent-shim/usage/snapshots/<identity>.json`) without shelling out to `agent-shim`.
8953
+ */
8954
+ declare const UsageSnapshotSchema: z.ZodObject<{
8955
+ schemaVersion: z.ZodLiteral<1>;
8956
+ identity: z.ZodString;
8957
+ updatedAt: z.ZodISODateTime;
8958
+ account: z.ZodOptional<z.ZodObject<{
8959
+ accountUuid: z.ZodOptional<z.ZodString>;
8960
+ emailAddress: z.ZodOptional<z.ZodString>;
8961
+ displayName: z.ZodOptional<z.ZodString>;
8962
+ organizationUuid: z.ZodOptional<z.ZodString>;
8963
+ organizationName: z.ZodOptional<z.ZodString>;
8964
+ organizationType: z.ZodOptional<z.ZodString>;
8965
+ organizationRole: z.ZodOptional<z.ZodString>;
8966
+ workspaceRole: z.ZodOptional<z.ZodString>;
8967
+ billingType: z.ZodOptional<z.ZodString>;
8968
+ seatTier: z.ZodOptional<z.ZodString>;
8969
+ organizationRateLimitTier: z.ZodOptional<z.ZodString>;
8970
+ userRateLimitTier: z.ZodOptional<z.ZodString>;
8971
+ hasExtraUsageEnabled: z.ZodOptional<z.ZodBoolean>;
8972
+ subscriptionCreatedAt: z.ZodOptional<z.ZodString>;
8973
+ accountCreatedAt: z.ZodOptional<z.ZodString>;
8974
+ }, z.core.$strict>>;
8975
+ providers: z.ZodRecord<z.ZodString, z.ZodObject<{
8976
+ lastRequestAt: z.ZodOptional<z.ZodISODateTime>;
8977
+ lastStatus: z.ZodOptional<z.ZodNumber>;
8978
+ lastModel: z.ZodOptional<z.ZodString>;
8979
+ rateLimit: z.ZodOptional<z.ZodObject<{
8980
+ observedAt: z.ZodISODateTime;
8981
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
8982
+ unified: z.ZodOptional<z.ZodObject<{
8983
+ status: z.ZodOptional<z.ZodString>;
8984
+ fiveHour: z.ZodOptional<z.ZodObject<{
8985
+ utilization: z.ZodOptional<z.ZodNumber>;
8986
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
8987
+ status: z.ZodOptional<z.ZodString>;
8988
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
8989
+ }, z.core.$strict>>;
8990
+ sevenDay: z.ZodOptional<z.ZodObject<{
8991
+ utilization: z.ZodOptional<z.ZodNumber>;
8992
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
8993
+ status: z.ZodOptional<z.ZodString>;
8994
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
8995
+ }, z.core.$strict>>;
8996
+ sevenDayOverageIncluded: z.ZodOptional<z.ZodObject<{
8997
+ utilization: z.ZodOptional<z.ZodNumber>;
8998
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
8999
+ status: z.ZodOptional<z.ZodString>;
9000
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
9001
+ }, z.core.$strict>>;
9002
+ representativeClaim: z.ZodOptional<z.ZodString>;
9003
+ resetAt: z.ZodOptional<z.ZodISODateTime>;
9004
+ overageStatus: z.ZodOptional<z.ZodString>;
9005
+ overageUtilization: z.ZodOptional<z.ZodNumber>;
9006
+ overageResetsAt: z.ZodOptional<z.ZodISODateTime>;
9007
+ overageDisabledReason: z.ZodOptional<z.ZodString>;
9008
+ overageInUse: z.ZodOptional<z.ZodBoolean>;
9009
+ extraUsageSpend: z.ZodOptional<z.ZodObject<{
9010
+ usedMinor: z.ZodNumber;
9011
+ limitMinor: z.ZodOptional<z.ZodNumber>;
9012
+ currency: z.ZodString;
9013
+ }, z.core.$strict>>;
9014
+ fallbackAvailable: z.ZodOptional<z.ZodBoolean>;
9015
+ }, z.core.$strict>>;
9016
+ planWindowsUnavailableAt: z.ZodOptional<z.ZodISODateTime>;
9017
+ }, z.core.$strict>>;
9018
+ lastLimit: z.ZodOptional<z.ZodObject<{
9019
+ kind: z.ZodEnum<{
9020
+ "rate-limited": "rate-limited";
9021
+ "quota-exhausted": "quota-exhausted";
9022
+ }>;
9023
+ retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
9024
+ resetAt: z.ZodOptional<z.ZodISODateTime>;
9025
+ window: z.ZodOptional<z.ZodString>;
9026
+ evidence: z.ZodArray<z.ZodString>;
9027
+ observedAt: z.ZodISODateTime;
9028
+ status: z.ZodNumber;
9029
+ }, z.core.$strict>>;
9030
+ quota: z.ZodOptional<z.ZodObject<{
9031
+ observedAt: z.ZodISODateTime;
9032
+ source: z.ZodString;
9033
+ level: z.ZodOptional<z.ZodString>;
9034
+ account: z.ZodOptional<z.ZodObject<{
9035
+ email: z.ZodOptional<z.ZodString>;
9036
+ accountId: z.ZodOptional<z.ZodString>;
9037
+ }, z.core.$strict>>;
9038
+ windows: z.ZodArray<z.ZodObject<{
9039
+ measures: z.ZodString;
9040
+ periodMs: z.ZodOptional<z.ZodNumber>;
9041
+ period: z.ZodOptional<z.ZodString>;
9042
+ utilization: z.ZodNumber;
9043
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
9044
+ limit: z.ZodOptional<z.ZodNumber>;
9045
+ used: z.ZodOptional<z.ZodNumber>;
9046
+ remaining: z.ZodOptional<z.ZodNumber>;
9047
+ }, z.core.$strict>>;
9048
+ }, z.core.$strict>>;
9049
+ }, z.core.$strict>>;
9050
+ }, z.core.$strict>;
9051
+ type UsageSnapshot = z.infer<typeof UsageSnapshotSchema>;
9052
+
8879
9053
  /**
8880
9054
  * How the allowlist the headroom daemon serves lags the allowlist computed now. The daemon re-reads its allowlist file on every request that follows a change to it, and its supervisor rewrites the file and records the hash in the same tick, so a lag that lasts beyond one tick means the supervisor is not running or cannot write the file. A daemon started by an earlier release reads no file, and is reported as such instead.
8881
9055
  */
@@ -9085,6 +9259,8 @@ interface DoctorIdentityInput {
9085
9259
  readonly farmRoot: string;
9086
9260
  /** Whether the identity's `.credentials.json` exists, pre-resolved by the wiring layer since it is a file-existence check. */
9087
9261
  readonly credentialsFilePresent: boolean;
9262
+ /** The account metadata of the identity's stored login, pre-resolved by the wiring layer since it is a read of the identity's `.claude.json`. Undefined when the identity has no stored login or its metadata cannot be read. */
9263
+ readonly account: AccountMetadata | undefined;
9088
9264
  }
9089
9265
  /** One configuration profile's raw `<name>.json`, unparsed. */
9090
9266
  interface DoctorConfigProfileInput {
@@ -9192,180 +9368,6 @@ interface CollectDoctorReportParams {
9192
9368
  */
9193
9369
  declare function collectDoctorReport(params: CollectDoctorReportParams): DoctorReport;
9194
9370
 
9195
- /** One routed request, appended to the usage log when its response has finished. */
9196
- declare const UsageRecordSchema: z.ZodObject<{
9197
- schemaVersion: z.ZodLiteral<1>;
9198
- at: z.ZodISODateTime;
9199
- identity: z.ZodOptional<z.ZodString>;
9200
- provider: z.ZodString;
9201
- sessionId: z.ZodOptional<z.ZodString>;
9202
- clientSessionId: z.ZodOptional<z.ZodString>;
9203
- project: z.ZodOptional<z.ZodString>;
9204
- viaHeadroom: z.ZodOptional<z.ZodBoolean>;
9205
- route: z.ZodString;
9206
- method: z.ZodString;
9207
- endpoint: z.ZodString;
9208
- model: z.ZodOptional<z.ZodString>;
9209
- requestedModel: z.ZodOptional<z.ZodString>;
9210
- candidateProviders: z.ZodOptional<z.ZodArray<z.ZodString>>;
9211
- status: z.ZodNumber;
9212
- latencyMs: z.ZodNumber;
9213
- durationMs: z.ZodNumber;
9214
- outcome: z.ZodEnum<{
9215
- completed: "completed";
9216
- aborted: "aborted";
9217
- }>;
9218
- usage: z.ZodOptional<z.ZodObject<{
9219
- inputTokens: z.ZodOptional<z.ZodNumber>;
9220
- outputTokens: z.ZodOptional<z.ZodNumber>;
9221
- cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
9222
- cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
9223
- }, z.core.$strict>>;
9224
- rateLimitHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
9225
- limit: z.ZodOptional<z.ZodObject<{
9226
- kind: z.ZodEnum<{
9227
- "rate-limited": "rate-limited";
9228
- "quota-exhausted": "quota-exhausted";
9229
- }>;
9230
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
9231
- resetAt: z.ZodOptional<z.ZodISODateTime>;
9232
- window: z.ZodOptional<z.ZodString>;
9233
- evidence: z.ZodArray<z.ZodString>;
9234
- }, z.core.$strict>>;
9235
- requestId: z.ZodOptional<z.ZodString>;
9236
- }, z.core.$strict>;
9237
- type UsageRecord = z.infer<typeof UsageRecordSchema>;
9238
- /** One quota window from Anthropic's unified rate-limit headers. */
9239
- declare const QuotaWindowSchema: z.ZodObject<{
9240
- utilization: z.ZodOptional<z.ZodNumber>;
9241
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
9242
- status: z.ZodOptional<z.ZodString>;
9243
- graceUtilization: z.ZodOptional<z.ZodNumber>;
9244
- }, z.core.$strict>;
9245
- type QuotaWindow = z.infer<typeof QuotaWindowSchema>;
9246
- /**
9247
- * The account fields copied from an identity's stored Claude login (`oauthAccount` in the identity's `.claude.json`): who the account is and which plan and tier it is on. Never the token, which Claude Code keeps elsewhere. Each field is present only when the stored login has it; a setup-token identity has no profile scope and so none of them (see issue #44).
9248
- */
9249
- declare const AccountMetadataSchema: z.ZodObject<{
9250
- accountUuid: z.ZodOptional<z.ZodString>;
9251
- emailAddress: z.ZodOptional<z.ZodString>;
9252
- displayName: z.ZodOptional<z.ZodString>;
9253
- organizationUuid: z.ZodOptional<z.ZodString>;
9254
- organizationName: z.ZodOptional<z.ZodString>;
9255
- organizationType: z.ZodOptional<z.ZodString>;
9256
- organizationRole: z.ZodOptional<z.ZodString>;
9257
- workspaceRole: z.ZodOptional<z.ZodString>;
9258
- billingType: z.ZodOptional<z.ZodString>;
9259
- seatTier: z.ZodOptional<z.ZodString>;
9260
- organizationRateLimitTier: z.ZodOptional<z.ZodString>;
9261
- userRateLimitTier: z.ZodOptional<z.ZodString>;
9262
- hasExtraUsageEnabled: z.ZodOptional<z.ZodBoolean>;
9263
- subscriptionCreatedAt: z.ZodOptional<z.ZodString>;
9264
- accountCreatedAt: z.ZodOptional<z.ZodString>;
9265
- }, z.core.$strict>;
9266
- type AccountMetadata = z.infer<typeof AccountMetadataSchema>;
9267
- /**
9268
- * The latest state for one identity, rewritten atomically after each recorded response: the snapshot file other tools read (`~/.agent-shim/usage/snapshots/<identity>.json`) without shelling out to `agent-shim`.
9269
- */
9270
- declare const UsageSnapshotSchema: z.ZodObject<{
9271
- schemaVersion: z.ZodLiteral<1>;
9272
- identity: z.ZodString;
9273
- updatedAt: z.ZodISODateTime;
9274
- account: z.ZodOptional<z.ZodObject<{
9275
- accountUuid: z.ZodOptional<z.ZodString>;
9276
- emailAddress: z.ZodOptional<z.ZodString>;
9277
- displayName: z.ZodOptional<z.ZodString>;
9278
- organizationUuid: z.ZodOptional<z.ZodString>;
9279
- organizationName: z.ZodOptional<z.ZodString>;
9280
- organizationType: z.ZodOptional<z.ZodString>;
9281
- organizationRole: z.ZodOptional<z.ZodString>;
9282
- workspaceRole: z.ZodOptional<z.ZodString>;
9283
- billingType: z.ZodOptional<z.ZodString>;
9284
- seatTier: z.ZodOptional<z.ZodString>;
9285
- organizationRateLimitTier: z.ZodOptional<z.ZodString>;
9286
- userRateLimitTier: z.ZodOptional<z.ZodString>;
9287
- hasExtraUsageEnabled: z.ZodOptional<z.ZodBoolean>;
9288
- subscriptionCreatedAt: z.ZodOptional<z.ZodString>;
9289
- accountCreatedAt: z.ZodOptional<z.ZodString>;
9290
- }, z.core.$strict>>;
9291
- providers: z.ZodRecord<z.ZodString, z.ZodObject<{
9292
- lastRequestAt: z.ZodOptional<z.ZodISODateTime>;
9293
- lastStatus: z.ZodOptional<z.ZodNumber>;
9294
- lastModel: z.ZodOptional<z.ZodString>;
9295
- rateLimit: z.ZodOptional<z.ZodObject<{
9296
- observedAt: z.ZodISODateTime;
9297
- headers: z.ZodRecord<z.ZodString, z.ZodString>;
9298
- unified: z.ZodOptional<z.ZodObject<{
9299
- status: z.ZodOptional<z.ZodString>;
9300
- fiveHour: z.ZodOptional<z.ZodObject<{
9301
- utilization: z.ZodOptional<z.ZodNumber>;
9302
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
9303
- status: z.ZodOptional<z.ZodString>;
9304
- graceUtilization: z.ZodOptional<z.ZodNumber>;
9305
- }, z.core.$strict>>;
9306
- sevenDay: z.ZodOptional<z.ZodObject<{
9307
- utilization: z.ZodOptional<z.ZodNumber>;
9308
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
9309
- status: z.ZodOptional<z.ZodString>;
9310
- graceUtilization: z.ZodOptional<z.ZodNumber>;
9311
- }, z.core.$strict>>;
9312
- sevenDayOverageIncluded: z.ZodOptional<z.ZodObject<{
9313
- utilization: z.ZodOptional<z.ZodNumber>;
9314
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
9315
- status: z.ZodOptional<z.ZodString>;
9316
- graceUtilization: z.ZodOptional<z.ZodNumber>;
9317
- }, z.core.$strict>>;
9318
- representativeClaim: z.ZodOptional<z.ZodString>;
9319
- resetAt: z.ZodOptional<z.ZodISODateTime>;
9320
- overageStatus: z.ZodOptional<z.ZodString>;
9321
- overageUtilization: z.ZodOptional<z.ZodNumber>;
9322
- overageResetsAt: z.ZodOptional<z.ZodISODateTime>;
9323
- overageDisabledReason: z.ZodOptional<z.ZodString>;
9324
- overageInUse: z.ZodOptional<z.ZodBoolean>;
9325
- extraUsageSpend: z.ZodOptional<z.ZodObject<{
9326
- usedMinor: z.ZodNumber;
9327
- limitMinor: z.ZodOptional<z.ZodNumber>;
9328
- currency: z.ZodString;
9329
- }, z.core.$strict>>;
9330
- fallbackAvailable: z.ZodOptional<z.ZodBoolean>;
9331
- }, z.core.$strict>>;
9332
- planWindowsUnavailableAt: z.ZodOptional<z.ZodISODateTime>;
9333
- }, z.core.$strict>>;
9334
- lastLimit: z.ZodOptional<z.ZodObject<{
9335
- kind: z.ZodEnum<{
9336
- "rate-limited": "rate-limited";
9337
- "quota-exhausted": "quota-exhausted";
9338
- }>;
9339
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
9340
- resetAt: z.ZodOptional<z.ZodISODateTime>;
9341
- window: z.ZodOptional<z.ZodString>;
9342
- evidence: z.ZodArray<z.ZodString>;
9343
- observedAt: z.ZodISODateTime;
9344
- status: z.ZodNumber;
9345
- }, z.core.$strict>>;
9346
- quota: z.ZodOptional<z.ZodObject<{
9347
- observedAt: z.ZodISODateTime;
9348
- source: z.ZodString;
9349
- level: z.ZodOptional<z.ZodString>;
9350
- account: z.ZodOptional<z.ZodObject<{
9351
- email: z.ZodOptional<z.ZodString>;
9352
- accountId: z.ZodOptional<z.ZodString>;
9353
- }, z.core.$strict>>;
9354
- windows: z.ZodArray<z.ZodObject<{
9355
- measures: z.ZodString;
9356
- periodMs: z.ZodOptional<z.ZodNumber>;
9357
- period: z.ZodOptional<z.ZodString>;
9358
- utilization: z.ZodNumber;
9359
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
9360
- limit: z.ZodOptional<z.ZodNumber>;
9361
- used: z.ZodOptional<z.ZodNumber>;
9362
- remaining: z.ZodOptional<z.ZodNumber>;
9363
- }, z.core.$strict>>;
9364
- }, z.core.$strict>>;
9365
- }, z.core.$strict>>;
9366
- }, z.core.$strict>;
9367
- type UsageSnapshot = z.infer<typeof UsageSnapshotSchema>;
9368
-
9369
9371
  /** How a sign-out went: whether OpenAI was told, so the person knows the grant is dead on its side too. */
9370
9372
  interface SiwcLogoutResult {
9371
9373
  readonly hadGrant: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "11.77.0",
3
+ "version": "11.78.0",
4
4
  "description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
5
5
  "license": "MIT",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",