agent-shim 11.79.0 → 11.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli.cjs +215 -87
- package/dist/index.cjs +161 -70
- package/dist/index.mjs +161 -70
- package/dist/types/index.d.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ That's it — with no further configuration, everything in `~/.claude` that isn'
|
|
|
57
57
|
- **An identity** is a login: the thing that owns credentials and daemon state, selected with `agent-shim run @<name>` or, once `agent-shim shim enable` has run, `claude @<name>`.
|
|
58
58
|
- **A configuration profile** is a reusable, named bundle of sharing rules, independent of any identity, resolved per working directory via directory rules or a committed `.agent-shim.json`.
|
|
59
59
|
|
|
60
|
-
A third, optional thing sits on top of identities: **a pool** is a named list of them. Select `pool:<name>` where an identity name goes (`claude @pool:subs`) and agent-shim picks the member whose unused quota is closest to expiring, skipping any that are refused right now, using the usage it already records. A pool can instead declare `--preference listed`, which tries the members in the order the pool lists them, skipping only one that is refused right now. A member entry may itself name another pool (`pool:<name>`), which is ranked with its own policy and contributes its pick at that position, so "this identity first, then the fleet" nests the fleet rather than copying its member list; cycles are refused. See [docs/configuration-model.md](docs/configuration-model.md#pools-picking-an-account-at-launch). On a terminal, `agent-shim run` asks which identity to run as when none resolves, when a pool pick would change account, or when the identity is refused right now (`--pick` forces the question, `--no-pick` never asks); see [docs/configuration-model.md](docs/configuration-model.md#choosing-the-identity-at-launch-the-picker).
|
|
60
|
+
A third, optional thing sits on top of identities: **a pool** is a named list of them. Select `pool:<name>` where an identity name goes (`claude @pool:subs`) and agent-shim picks the member whose unused quota is closest to expiring, skipping any that are refused right now, using the usage it already records. A pool can instead declare `--preference listed`, which tries the members in the order the pool lists them, skipping only one that is refused right now. A member entry may itself name another pool (`pool:<name>`), which is ranked with its own policy and contributes its pick at that position, so "this identity first, then the fleet" nests the fleet rather than copying its member list; cycles are refused. Members that hold the same login (the same account in the same organisation) share one quota window, so a pool ranks them as one candidate and never fails over from one to the other; `pool add`, `pool set` and `doctor` warn when a pool lists two of them. See [docs/configuration-model.md](docs/configuration-model.md#pools-picking-an-account-at-launch). On a terminal, `agent-shim run` asks which identity to run as when none resolves, when a pool pick would change account, or when the identity is refused right now (`--pick` forces the question, `--no-pick` never asks); see [docs/configuration-model.md](docs/configuration-model.md#choosing-the-identity-at-launch-the-picker).
|
|
61
61
|
|
|
62
62
|
Every top-level entry in `~/.claude` is classified into one of five categories, shipped as a default map (`config/categories.default.json`):
|
|
63
63
|
|
|
@@ -85,7 +85,7 @@ agent-shim <noun> <verb> [name] [options] # nouns: identity, profile, pool,
|
|
|
85
85
|
agent-shim identity add <name> [--json]
|
|
86
86
|
agent-shim identity list [--json]
|
|
87
87
|
agent-shim identity show <name> [--json]
|
|
88
|
-
agent-shim identity set <name> [--default-profile <profile> | --no-default-profile] [--provider <provider> | --no-provider] [--[no-]allow-ambient-credential] [--json]
|
|
88
|
+
agent-shim identity set <name> [--label <text> | --no-label] [--default-profile <profile> | --no-default-profile] [--provider <provider> | --no-provider] [--[no-]allow-ambient-credential] [--json]
|
|
89
89
|
agent-shim identity set <name> [--credential <source>]... [--credential-target <bearer|apiKey|oauthToken>] [--no-credential] [--json]
|
|
90
90
|
agent-shim identity set <name> [--anchor <days>@<HH:MM>[/<zone>]]... [--no-anchor] [--json]
|
|
91
91
|
agent-shim identity remove <name> [--yes] [--json]
|
package/dist/cli.cjs
CHANGED
|
@@ -25123,7 +25123,7 @@ function providerFilePath(directory, name, source) {
|
|
|
25123
25123
|
}
|
|
25124
25124
|
return import_node_path4.default.join(directory, `${name}.json`);
|
|
25125
25125
|
}
|
|
25126
|
-
var import_node_path4, FILESYSTEM_COMPONENT_BYTES, MAX_PID_DIGITS, UUID_CHARS, ATOMIC_WRITE_OVERHEAD_BYTES, FARM_SWAP_OVERHEAD_BYTES, MAX_NAME_BYTES, FILE_NAME_PATTERN, FILE_NAME, FILE_NAME_RULE, STORED_NAME_RULE, FileNameSchema, StoredNameSchema, UnsafeNameError, InvalidProviderNameError;
|
|
25126
|
+
var import_node_path4, FILESYSTEM_COMPONENT_BYTES, MAX_PID_DIGITS, UUID_CHARS, ATOMIC_WRITE_OVERHEAD_BYTES, FARM_SWAP_OVERHEAD_BYTES, MAX_NAME_BYTES, FILE_NAME_PATTERN, FILE_NAME, FILE_NAME_RULE, STORED_NAME_RULE, FileNameSchema, StoredNameSchema, LABEL_FORBIDDEN, IDENTITY_LABEL_RULE, IdentityLabelSchema, UnsafeNameError, InvalidProviderNameError;
|
|
25127
25127
|
var init_names = __esm({
|
|
25128
25128
|
"src/config/names.ts"() {
|
|
25129
25129
|
"use strict";
|
|
@@ -25142,6 +25142,9 @@ var init_names = __esm({
|
|
|
25142
25142
|
STORED_NAME_RULE = `must be non-empty, at most ${String(MAX_NAME_BYTES)} bytes, not "." or "..", and contain no path separator or NUL`;
|
|
25143
25143
|
FileNameSchema = external_exports.string().min(1).regex(FILE_NAME, FILE_NAME_RULE);
|
|
25144
25144
|
StoredNameSchema = external_exports.string().min(1).max(MAX_NAME_BYTES).refine(isStoredName, STORED_NAME_RULE);
|
|
25145
|
+
LABEL_FORBIDDEN = /[\p{Cc}\p{Zl}\p{Zp}]/u;
|
|
25146
|
+
IDENTITY_LABEL_RULE = `must be non-empty single-line text of at most ${String(MAX_NAME_BYTES)} characters, with no control characters and no leading or trailing whitespace`;
|
|
25147
|
+
IdentityLabelSchema = external_exports.string().min(1).max(MAX_NAME_BYTES).refine((label2) => label2 === label2.trim() && !LABEL_FORBIDDEN.test(label2), IDENTITY_LABEL_RULE);
|
|
25145
25148
|
UnsafeNameError = class extends CliError {
|
|
25146
25149
|
constructor(attemptedName, kind, rule = STORED_NAME_RULE, source) {
|
|
25147
25150
|
super(`${source === void 0 ? "" : `${source}: `}${JSON.stringify(attemptedName)} is not a valid ${kind} name: a name ${rule}.`);
|
|
@@ -28489,6 +28492,8 @@ var init_schema = __esm({
|
|
|
28489
28492
|
IdentitySchema = external_exports.strictObject({
|
|
28490
28493
|
$schema: external_exports.string().optional(),
|
|
28491
28494
|
name: FileNameSchema,
|
|
28495
|
+
/** What the identity is for, in the person's words, drawn beside its name in `identity list` and `show`, the launch banner and the statusline. Display only: the name stays the key for lookup, paths, keychain service names and pools. */
|
|
28496
|
+
label: IdentityLabelSchema.optional(),
|
|
28492
28497
|
defaultConfigProfile: StoredNameSchema.optional(),
|
|
28493
28498
|
/** The provider this identity exists for: a launch on the identity routes through it unless `--provider`, `--no-provider` or a cascade layer's `launch.provider` says otherwise. Its sessions run on the provider's credential, so the identity needs no stored login. */
|
|
28494
28499
|
provider: StoredNameSchema.optional(),
|
|
@@ -38192,13 +38197,95 @@ var init_account = __esm({
|
|
|
38192
38197
|
}
|
|
38193
38198
|
});
|
|
38194
38199
|
|
|
38200
|
+
// src/usage/accountDescription.ts
|
|
38201
|
+
function describeAccountOrganisation(account) {
|
|
38202
|
+
const parts = [account.organizationName, account.organizationType].filter((part) => part !== void 0);
|
|
38203
|
+
return parts.length === 0 ? void 0 : parts.join(", ");
|
|
38204
|
+
}
|
|
38205
|
+
function describeAccountPlan(account) {
|
|
38206
|
+
const parts = [account.billingType === void 0 ? void 0 : `billing ${account.billingType}`, account.seatTier === void 0 ? void 0 : `seat tier ${account.seatTier}`].filter((part) => part !== void 0);
|
|
38207
|
+
return parts.length === 0 ? void 0 : parts.join(", ");
|
|
38208
|
+
}
|
|
38209
|
+
var init_accountDescription = __esm({
|
|
38210
|
+
"src/usage/accountDescription.ts"() {
|
|
38211
|
+
"use strict";
|
|
38212
|
+
}
|
|
38213
|
+
});
|
|
38214
|
+
|
|
38215
|
+
// src/identityAccounts.ts
|
|
38216
|
+
function readIdentityAccount(fs31, identitiesDir, identity) {
|
|
38217
|
+
try {
|
|
38218
|
+
const account = readAccountMetadata(fs31, identitiesDir, identity);
|
|
38219
|
+
return account === void 0 ? void 0 : { account };
|
|
38220
|
+
} catch (error63) {
|
|
38221
|
+
if (error63 instanceof AccountMetadataError) {
|
|
38222
|
+
return { problem: error63.message };
|
|
38223
|
+
}
|
|
38224
|
+
throw error63;
|
|
38225
|
+
}
|
|
38226
|
+
}
|
|
38227
|
+
function summariseIdentityAccount(account) {
|
|
38228
|
+
const summary = {
|
|
38229
|
+
...account.emailAddress === void 0 ? {} : { emailAddress: account.emailAddress },
|
|
38230
|
+
...account.organizationName === void 0 ? {} : { organizationName: account.organizationName },
|
|
38231
|
+
...account.organizationType === void 0 ? {} : { organizationType: account.organizationType },
|
|
38232
|
+
...account.organizationRole === void 0 ? {} : { organizationRole: account.organizationRole },
|
|
38233
|
+
...account.billingType === void 0 ? {} : { billingType: account.billingType },
|
|
38234
|
+
...account.seatTier === void 0 ? {} : { seatTier: account.seatTier }
|
|
38235
|
+
};
|
|
38236
|
+
return Object.keys(summary).length === 0 ? void 0 : summary;
|
|
38237
|
+
}
|
|
38238
|
+
function loginKeyOf(account) {
|
|
38239
|
+
return account.accountUuid === void 0 ? void 0 : JSON.stringify([account.accountUuid, account.organizationUuid ?? null]);
|
|
38240
|
+
}
|
|
38241
|
+
function collectByLogin(items, loginOf) {
|
|
38242
|
+
const groups = /* @__PURE__ */ new Map();
|
|
38243
|
+
for (const item of items) {
|
|
38244
|
+
const key = loginOf(item) ?? /* @__PURE__ */ Symbol("no login");
|
|
38245
|
+
const group = groups.get(key);
|
|
38246
|
+
if (group === void 0) {
|
|
38247
|
+
groups.set(key, [item]);
|
|
38248
|
+
} else {
|
|
38249
|
+
group.push(item);
|
|
38250
|
+
}
|
|
38251
|
+
}
|
|
38252
|
+
return [...groups.values()];
|
|
38253
|
+
}
|
|
38254
|
+
function groupByLogin(items, loginOf) {
|
|
38255
|
+
return collectByLogin(items, loginOf).flat();
|
|
38256
|
+
}
|
|
38257
|
+
function groupSharedLogins(items, loginOf) {
|
|
38258
|
+
return collectByLogin(items, loginOf).filter((group) => group.length > 1);
|
|
38259
|
+
}
|
|
38260
|
+
function joinNames(names) {
|
|
38261
|
+
const last = names.at(-1);
|
|
38262
|
+
return names.length < 2 || last === void 0 ? names.join("") : `${names.slice(0, -1).join(", ")} and ${last}`;
|
|
38263
|
+
}
|
|
38264
|
+
function describeAccountHolder(summary) {
|
|
38265
|
+
const organisation = describeAccountOrganisation(summary);
|
|
38266
|
+
if (summary.emailAddress === void 0) {
|
|
38267
|
+
return organisation;
|
|
38268
|
+
}
|
|
38269
|
+
return organisation === void 0 ? summary.emailAddress : `${summary.emailAddress} (${organisation})`;
|
|
38270
|
+
}
|
|
38271
|
+
function describeIdentityAccount(summary) {
|
|
38272
|
+
return [describeAccountHolder(summary), summary.organizationRole === void 0 ? void 0 : `role ${summary.organizationRole}`, describeAccountPlan(summary)].filter((part) => part !== void 0).join("; ");
|
|
38273
|
+
}
|
|
38274
|
+
var init_identityAccounts = __esm({
|
|
38275
|
+
"src/identityAccounts.ts"() {
|
|
38276
|
+
"use strict";
|
|
38277
|
+
init_account();
|
|
38278
|
+
init_accountDescription();
|
|
38279
|
+
}
|
|
38280
|
+
});
|
|
38281
|
+
|
|
38195
38282
|
// package.json
|
|
38196
38283
|
var package_default;
|
|
38197
38284
|
var init_package = __esm({
|
|
38198
38285
|
"package.json"() {
|
|
38199
38286
|
package_default = {
|
|
38200
38287
|
name: "agent-shim",
|
|
38201
|
-
version: "11.
|
|
38288
|
+
version: "11.81.0",
|
|
38202
38289
|
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
38290
|
license: "MIT",
|
|
38204
38291
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -38918,6 +39005,9 @@ function assessRefusedNested(member, nested, nowMs) {
|
|
|
38918
39005
|
};
|
|
38919
39006
|
}
|
|
38920
39007
|
function assess(member, nowMs) {
|
|
39008
|
+
if (member.sameLoginAs !== void 0) {
|
|
39009
|
+
return { candidate: { identity: member.identity, class: "ineligible", plan: planOf(member.account), reasons: [`same login as ${member.sameLoginAs}`] } };
|
|
39010
|
+
}
|
|
38921
39011
|
const nested = member.nested;
|
|
38922
39012
|
if (nested === void 0) {
|
|
38923
39013
|
return assessIdentity(member, nowMs);
|
|
@@ -39461,6 +39551,29 @@ function loadPoolMembers(fs31, paths, identities, nowMs) {
|
|
|
39461
39551
|
}
|
|
39462
39552
|
});
|
|
39463
39553
|
}
|
|
39554
|
+
function snapshotAgeKey(member) {
|
|
39555
|
+
return member.snapshot === void 0 ? Number.NEGATIVE_INFINITY : Date.parse(member.snapshot.updatedAt);
|
|
39556
|
+
}
|
|
39557
|
+
function collapseSharedLogins(members2) {
|
|
39558
|
+
const groups = groupSharedLogins(members2, (member) => member.nested === void 0 && member.account !== void 0 ? loginKeyOf(member.account) : void 0);
|
|
39559
|
+
const representativeOf = /* @__PURE__ */ new Map();
|
|
39560
|
+
for (const group of groups) {
|
|
39561
|
+
const representative = group.reduce((freshest, member) => snapshotAgeKey(member) > snapshotAgeKey(freshest) ? member : freshest);
|
|
39562
|
+
for (const member of group) {
|
|
39563
|
+
if (member !== representative) {
|
|
39564
|
+
representativeOf.set(member, representative.identity);
|
|
39565
|
+
}
|
|
39566
|
+
}
|
|
39567
|
+
}
|
|
39568
|
+
return members2.map((member) => {
|
|
39569
|
+
const representative = representativeOf.get(member);
|
|
39570
|
+
return representative === void 0 ? member : { ...member, sameLoginAs: representative };
|
|
39571
|
+
});
|
|
39572
|
+
}
|
|
39573
|
+
function stickyOnRepresentative(sticky, members2) {
|
|
39574
|
+
const twin = sticky === void 0 ? void 0 : members2.find((member) => member.identity === sticky.identity && member.sameLoginAs !== void 0);
|
|
39575
|
+
return sticky === void 0 || twin?.sameLoginAs === void 0 ? sticky : { ...sticky, identity: twin.sameLoginAs };
|
|
39576
|
+
}
|
|
39464
39577
|
function rankPoolGraph(input2) {
|
|
39465
39578
|
return rankNamedPool(input2, input2.poolName, [], input2.sticky);
|
|
39466
39579
|
}
|
|
@@ -39488,13 +39601,15 @@ function rankNamedPool(input2, poolName, stack, sticky) {
|
|
|
39488
39601
|
members2.push(typeof entry === "string" ? nested.member : { ...nested.member, policy: entry.when });
|
|
39489
39602
|
missing.push(...nested.missing);
|
|
39490
39603
|
}
|
|
39604
|
+
const collapsed = collapseSharedLogins(members2);
|
|
39605
|
+
const stickyPick = stickyOnRepresentative(sticky, collapsed);
|
|
39491
39606
|
const ranking = rankPool({
|
|
39492
|
-
members:
|
|
39607
|
+
members: collapsed,
|
|
39493
39608
|
nowMs: input2.nowMs,
|
|
39494
39609
|
resuming: input2.resuming,
|
|
39495
39610
|
...input2.resumeContextTokens === void 0 ? {} : { resumeContextTokens: input2.resumeContextTokens },
|
|
39496
39611
|
...input2.committedContextTokens === void 0 ? {} : { committedContextTokens: input2.committedContextTokens },
|
|
39497
|
-
...
|
|
39612
|
+
...stickyPick === void 0 ? {} : { sticky: stickyPick },
|
|
39498
39613
|
...pool.preference === void 0 ? {} : { preference: pool.preference }
|
|
39499
39614
|
});
|
|
39500
39615
|
return { ranking, missing };
|
|
@@ -39561,6 +39676,7 @@ var init_poolPick = __esm({
|
|
|
39561
39676
|
init_cliError();
|
|
39562
39677
|
init_identity();
|
|
39563
39678
|
init_schema();
|
|
39679
|
+
init_identityAccounts();
|
|
39564
39680
|
init_account();
|
|
39565
39681
|
init_pick();
|
|
39566
39682
|
init_read();
|
|
@@ -67997,9 +68113,15 @@ function movedRows(facts) {
|
|
|
67997
68113
|
}
|
|
67998
68114
|
return [];
|
|
67999
68115
|
}
|
|
68116
|
+
function identityText(facts) {
|
|
68117
|
+
if (facts.identity === void 0) {
|
|
68118
|
+
return "(none)";
|
|
68119
|
+
}
|
|
68120
|
+
return facts.identityLabel === void 0 ? facts.identity : `${facts.identity} (${facts.identityLabel})`;
|
|
68121
|
+
}
|
|
68000
68122
|
function decisionRows(facts) {
|
|
68001
68123
|
return [
|
|
68002
|
-
{ label: "identity", value: facts
|
|
68124
|
+
{ label: "identity", value: identityText(facts), detail: facts.identitySource },
|
|
68003
68125
|
...facts.pool === void 0 ? [] : [
|
|
68004
68126
|
{
|
|
68005
68127
|
label: "pool",
|
|
@@ -70165,6 +70287,7 @@ function decideLaunch(params, readOnly) {
|
|
|
70165
70287
|
return {
|
|
70166
70288
|
parsedArgv,
|
|
70167
70289
|
identityDecision,
|
|
70290
|
+
identityLabel: loadedIdentity?.config.label,
|
|
70168
70291
|
poolPick,
|
|
70169
70292
|
poolRanking,
|
|
70170
70293
|
lastRanAs,
|
|
@@ -70195,6 +70318,7 @@ function prepareLaunch(params) {
|
|
|
70195
70318
|
const rows = [
|
|
70196
70319
|
...decisionRows({
|
|
70197
70320
|
identity: identityDecision.name,
|
|
70321
|
+
identityLabel: decided.identityLabel,
|
|
70198
70322
|
identitySource: identityDecision.source,
|
|
70199
70323
|
pool: poolPick,
|
|
70200
70324
|
ranking: resolvedFlags.explain ? poolRanking : void 0,
|
|
@@ -116557,6 +116681,12 @@ function setIdentityProvider(paths, identityName, providerName) {
|
|
|
116557
116681
|
}
|
|
116558
116682
|
return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { provider: providerName });
|
|
116559
116683
|
}
|
|
116684
|
+
function setIdentityLabel(paths, identityName, label2) {
|
|
116685
|
+
if (!identityExists(paths, identityName)) {
|
|
116686
|
+
throw new IdentityNotFoundError(identityName);
|
|
116687
|
+
}
|
|
116688
|
+
return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { label: label2 });
|
|
116689
|
+
}
|
|
116560
116690
|
function setAllowAmbientCredential(paths, identityName, allow) {
|
|
116561
116691
|
if (!identityExists(paths, identityName)) {
|
|
116562
116692
|
throw new IdentityNotFoundError(identityName);
|
|
@@ -117701,80 +117831,12 @@ function registerProfileCommand(program2, deps) {
|
|
|
117701
117831
|
}
|
|
117702
117832
|
|
|
117703
117833
|
// src/identityManager.ts
|
|
117834
|
+
init_names();
|
|
117704
117835
|
init_providersStore();
|
|
117705
117836
|
init_identity();
|
|
117706
117837
|
init_realPorts();
|
|
117707
|
-
|
|
117708
|
-
|
|
117709
|
-
init_account();
|
|
117710
|
-
|
|
117711
|
-
// src/usage/accountDescription.ts
|
|
117712
|
-
function describeAccountOrganisation(account) {
|
|
117713
|
-
const parts = [account.organizationName, account.organizationType].filter((part) => part !== void 0);
|
|
117714
|
-
return parts.length === 0 ? void 0 : parts.join(", ");
|
|
117715
|
-
}
|
|
117716
|
-
function describeAccountPlan(account) {
|
|
117717
|
-
const parts = [account.billingType === void 0 ? void 0 : `billing ${account.billingType}`, account.seatTier === void 0 ? void 0 : `seat tier ${account.seatTier}`].filter((part) => part !== void 0);
|
|
117718
|
-
return parts.length === 0 ? void 0 : parts.join(", ");
|
|
117719
|
-
}
|
|
117720
|
-
|
|
117721
|
-
// src/identityAccounts.ts
|
|
117722
|
-
function readIdentityAccount(fs31, identitiesDir, identity) {
|
|
117723
|
-
try {
|
|
117724
|
-
const account = readAccountMetadata(fs31, identitiesDir, identity);
|
|
117725
|
-
return account === void 0 ? void 0 : { account };
|
|
117726
|
-
} catch (error63) {
|
|
117727
|
-
if (error63 instanceof AccountMetadataError) {
|
|
117728
|
-
return { problem: error63.message };
|
|
117729
|
-
}
|
|
117730
|
-
throw error63;
|
|
117731
|
-
}
|
|
117732
|
-
}
|
|
117733
|
-
function summariseIdentityAccount(account) {
|
|
117734
|
-
const summary = {
|
|
117735
|
-
...account.emailAddress === void 0 ? {} : { emailAddress: account.emailAddress },
|
|
117736
|
-
...account.organizationName === void 0 ? {} : { organizationName: account.organizationName },
|
|
117737
|
-
...account.organizationType === void 0 ? {} : { organizationType: account.organizationType },
|
|
117738
|
-
...account.organizationRole === void 0 ? {} : { organizationRole: account.organizationRole },
|
|
117739
|
-
...account.billingType === void 0 ? {} : { billingType: account.billingType },
|
|
117740
|
-
...account.seatTier === void 0 ? {} : { seatTier: account.seatTier }
|
|
117741
|
-
};
|
|
117742
|
-
return Object.keys(summary).length === 0 ? void 0 : summary;
|
|
117743
|
-
}
|
|
117744
|
-
function loginKeyOf(account) {
|
|
117745
|
-
return account.accountUuid === void 0 ? void 0 : JSON.stringify([account.accountUuid, account.organizationUuid ?? null]);
|
|
117746
|
-
}
|
|
117747
|
-
function collectByLogin(items, loginOf) {
|
|
117748
|
-
const groups = /* @__PURE__ */ new Map();
|
|
117749
|
-
for (const item of items) {
|
|
117750
|
-
const key = loginOf(item) ?? /* @__PURE__ */ Symbol("no login");
|
|
117751
|
-
const group = groups.get(key);
|
|
117752
|
-
if (group === void 0) {
|
|
117753
|
-
groups.set(key, [item]);
|
|
117754
|
-
} else {
|
|
117755
|
-
group.push(item);
|
|
117756
|
-
}
|
|
117757
|
-
}
|
|
117758
|
-
return [...groups.values()];
|
|
117759
|
-
}
|
|
117760
|
-
function groupByLogin(items, loginOf) {
|
|
117761
|
-
return collectByLogin(items, loginOf).flat();
|
|
117762
|
-
}
|
|
117763
|
-
function groupSharedLogins(items, loginOf) {
|
|
117764
|
-
return collectByLogin(items, loginOf).filter((group) => group.length > 1);
|
|
117765
|
-
}
|
|
117766
|
-
function describeAccountHolder(summary) {
|
|
117767
|
-
const organisation = describeAccountOrganisation(summary);
|
|
117768
|
-
if (summary.emailAddress === void 0) {
|
|
117769
|
-
return organisation;
|
|
117770
|
-
}
|
|
117771
|
-
return organisation === void 0 ? summary.emailAddress : `${summary.emailAddress} (${organisation})`;
|
|
117772
|
-
}
|
|
117773
|
-
function describeIdentityAccount(summary) {
|
|
117774
|
-
return [describeAccountHolder(summary), summary.organizationRole === void 0 ? void 0 : `role ${summary.organizationRole}`, describeAccountPlan(summary)].filter((part) => part !== void 0).join("; ");
|
|
117775
|
-
}
|
|
117776
|
-
|
|
117777
|
-
// src/identityManager.ts
|
|
117838
|
+
init_identityAccounts();
|
|
117839
|
+
init_accountDescription();
|
|
117778
117840
|
async function runIdentityWizard(prompts, paths, name, options = {}) {
|
|
117779
117841
|
if (!IdentitySchema.safeParse({ name, allowAmbientCredential: false }).success) {
|
|
117780
117842
|
throw new InvalidIdentityNameError(name);
|
|
@@ -117845,6 +117907,7 @@ function toIdentityView(paths, { entry, read }, sharesLoginWith) {
|
|
|
117845
117907
|
active: entry.isActive,
|
|
117846
117908
|
directory: import_node_path25.default.join(paths.identitiesDir, entry.name),
|
|
117847
117909
|
...entry.problem === void 0 ? {
|
|
117910
|
+
...entry.identity.label === void 0 ? {} : { label: entry.identity.label },
|
|
117848
117911
|
...entry.identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: entry.identity.defaultConfigProfile },
|
|
117849
117912
|
...entry.identity.provider === void 0 ? {} : { provider: entry.identity.provider },
|
|
117850
117913
|
allowAmbientCredential: entry.identity.allowAmbientCredential,
|
|
@@ -117872,11 +117935,12 @@ function formatIdentityLine(entry, view) {
|
|
|
117872
117935
|
if (entry.problem !== void 0) {
|
|
117873
117936
|
return `${marker}${entry.name} [unreadable: ${entry.problem}]${account}${accountProblem}`;
|
|
117874
117937
|
}
|
|
117938
|
+
const label2 = entry.identity.label === void 0 ? "" : ` (label: ${entry.identity.label})`;
|
|
117875
117939
|
const defaultProfile = entry.identity.defaultConfigProfile === void 0 ? "" : ` (default profile: ${entry.identity.defaultConfigProfile})`;
|
|
117876
117940
|
const provider = entry.identity.provider === void 0 ? "" : ` (provider: ${entry.identity.provider})`;
|
|
117877
117941
|
const ambient = entry.identity.allowAmbientCredential ? " [allows ambient credential]" : "";
|
|
117878
117942
|
const credential = entry.identity.credential === void 0 ? "" : ` [credential ${describeCredential(entry.identity.credential)}]`;
|
|
117879
|
-
return `${marker}${entry.name}${defaultProfile}${provider}${ambient}${credential}${account}${accountProblem}`;
|
|
117943
|
+
return `${marker}${entry.name}${label2}${defaultProfile}${provider}${ambient}${credential}${account}${accountProblem}`;
|
|
117880
117944
|
}
|
|
117881
117945
|
function registerIdentityCommand(program2, deps) {
|
|
117882
117946
|
const { paths } = deps;
|
|
@@ -117948,6 +118012,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117948
118012
|
console.log(`Unreadable: ${view.problem}`);
|
|
117949
118013
|
return;
|
|
117950
118014
|
}
|
|
118015
|
+
console.log(`Label: ${view.label ?? "(none)"}`);
|
|
117951
118016
|
console.log(`Default configuration profile: ${view.defaultConfigProfile ?? "(none)"}`);
|
|
117952
118017
|
console.log(`Provider: ${view.provider ?? "(none)"}`);
|
|
117953
118018
|
console.log(`Allows ambient credential: ${view.allowAmbientCredential === true ? "yes" : "no"}`);
|
|
@@ -117956,7 +118021,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117956
118021
|
}),
|
|
117957
118022
|
["agent-shim identity show work", "agent-shim identity show work --json"]
|
|
117958
118023
|
);
|
|
117959
|
-
const identitySet = identity.command("set <name>").description("Update an identity's settings.").option("--json", "Print the result as JSON.").option("--default-profile <profile>", "Configuration profile this identity uses when nothing more specific selects one.").option("--no-default-profile", "Clear this identity's default configuration profile.").option("--provider <provider>", "Provider this identity exists for: a launch on it routes through the provider unless a flag, directory rule or profile selects another, and doctor expects no stored login.").option("--no-provider", "Clear this identity's provider.").option("--allow-ambient-credential", "Allow this identity to launch even with an ambient credential env var set.").option("--no-allow-ambient-credential", "Disallow ambient credential env vars for this identity (the default).").option(
|
|
118024
|
+
const identitySet = identity.command("set <name>").description("Update an identity's settings.").option("--json", "Print the result as JSON.").option("--label <text>", "Free text shown beside this identity's name in `identity list` and `show`, the launch banner and the statusline. Display only: the name stays the key.").option("--no-label", "Clear this identity's label.").option("--default-profile <profile>", "Configuration profile this identity uses when nothing more specific selects one.").option("--no-default-profile", "Clear this identity's default configuration profile.").option("--provider <provider>", "Provider this identity exists for: a launch on it routes through the provider unless a flag, directory rule or profile selects another, and doctor expects no stored login.").option("--no-provider", "Clear this identity's provider.").option("--allow-ambient-credential", "Allow this identity to launch even with an ambient credential env var set.").option("--no-allow-ambient-credential", "Disallow ambient credential env vars for this identity (the default).").option(
|
|
117960
118025
|
"--credential <source>",
|
|
117961
118026
|
`Authenticate this identity from a token instead of its stored login, replacing any existing sources (repeatable, in the order tried): ${CREDENTIAL_SOURCE_SYNTAX}.`,
|
|
117962
118027
|
collectCredentialSource
|
|
@@ -117976,16 +118041,25 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117976
118041
|
const { json: json2, ...options } = allOptions;
|
|
117977
118042
|
if (Object.entries(allOptions).every(([key, value2]) => key === "json" || value2 === void 0)) {
|
|
117978
118043
|
throw new UsageError(
|
|
117979
|
-
"Nothing to change: pass --default-profile, --no-default-profile, --provider, --no-provider, --allow-ambient-credential, --no-allow-ambient-credential, --credential, --no-credential, --credential-target, --anchor, --no-anchor or a --credential-cache option."
|
|
118044
|
+
"Nothing to change: pass --label, --no-label, --default-profile, --no-default-profile, --provider, --no-provider, --allow-ambient-credential, --no-allow-ambient-credential, --credential, --no-credential, --credential-target, --anchor, --no-anchor or a --credential-cache option."
|
|
117980
118045
|
);
|
|
117981
118046
|
}
|
|
117982
118047
|
if (!identityExists(paths, name)) {
|
|
117983
118048
|
throw new IdentityNotFoundError(name);
|
|
117984
118049
|
}
|
|
118050
|
+
const label2 = typeof options.label === "string" ? IdentityLabelSchema.safeParse(options.label) : void 0;
|
|
118051
|
+
if (label2?.success === false) {
|
|
118052
|
+
throw new UsageError(`Identity label ${JSON.stringify(options.label)} ${IDENTITY_LABEL_RULE}.`);
|
|
118053
|
+
}
|
|
117985
118054
|
if (typeof options.provider === "string") {
|
|
117986
118055
|
requireProviderExists(paths, options.provider);
|
|
117987
118056
|
}
|
|
117988
118057
|
const messages = [];
|
|
118058
|
+
if (options.label !== void 0) {
|
|
118059
|
+
const labelText = options.label === false ? void 0 : options.label;
|
|
118060
|
+
setIdentityLabel(paths, name, labelText);
|
|
118061
|
+
messages.push(labelText === void 0 ? `Identity "${name}" no longer has a label.` : `Identity "${name}" is now labelled ${JSON.stringify(labelText)}.`);
|
|
118062
|
+
}
|
|
117989
118063
|
if (options.defaultProfile !== void 0) {
|
|
117990
118064
|
const profileName = options.defaultProfile === false ? void 0 : options.defaultProfile;
|
|
117991
118065
|
if (profileName !== void 0) {
|
|
@@ -118030,6 +118104,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
118030
118104
|
});
|
|
118031
118105
|
}),
|
|
118032
118106
|
[
|
|
118107
|
+
'agent-shim identity set work --label "Example Org"',
|
|
118033
118108
|
"agent-shim identity set work --default-profile client-acme",
|
|
118034
118109
|
"agent-shim identity set minimax --provider minimax",
|
|
118035
118110
|
"agent-shim identity set work --allow-ambient-credential",
|
|
@@ -123234,6 +123309,7 @@ init_realPorts();
|
|
|
123234
123309
|
var import_node_fs20 = __toESM(require("node:fs"), 1);
|
|
123235
123310
|
var import_node_path47 = __toESM(require("node:path"), 1);
|
|
123236
123311
|
init_signIn();
|
|
123312
|
+
init_identityAccounts();
|
|
123237
123313
|
init_load();
|
|
123238
123314
|
init_unrecognisedKeys();
|
|
123239
123315
|
init_schema();
|
|
@@ -123508,6 +123584,27 @@ init_providerAliases();
|
|
|
123508
123584
|
init_providersStore();
|
|
123509
123585
|
init_guard();
|
|
123510
123586
|
init_identity();
|
|
123587
|
+
|
|
123588
|
+
// src/poolSharedLogins.ts
|
|
123589
|
+
init_identityAccounts();
|
|
123590
|
+
init_identity();
|
|
123591
|
+
function sharedLoginMembers(members2, accountOf) {
|
|
123592
|
+
const known = members2.flatMap((identity) => {
|
|
123593
|
+
const account = poolNameOf(identity) === void 0 ? accountOf(identity) : void 0;
|
|
123594
|
+
return account === void 0 ? [] : [{ identity, account }];
|
|
123595
|
+
});
|
|
123596
|
+
return groupSharedLogins(known, (entry) => loginKeyOf(entry.account)).flatMap((group) => {
|
|
123597
|
+
const first = group[0];
|
|
123598
|
+
return first === void 0 ? [] : [{ members: group.map((entry) => entry.identity), account: first.account }];
|
|
123599
|
+
});
|
|
123600
|
+
}
|
|
123601
|
+
function describeSharedLoginMembers(poolName, shared) {
|
|
123602
|
+
const summary = summariseIdentityAccount(shared.account);
|
|
123603
|
+
const holder = summary === void 0 ? void 0 : describeAccountHolder(summary);
|
|
123604
|
+
return `Pool "${poolName}" lists ${joinNames(shared.members)}, which hold the same login${holder === void 0 ? "" : ` (${holder})`}, so they share one quota window. A launch ranks them as one candidate and never fails over from one to another; keep one of them in the pool.`;
|
|
123605
|
+
}
|
|
123606
|
+
|
|
123607
|
+
// src/doctorReport.ts
|
|
123511
123608
|
init_extends();
|
|
123512
123609
|
var DOCTOR_SEVERITIES = ["pass", "warn", "fail"];
|
|
123513
123610
|
var DOCTOR_SECTIONS = [
|
|
@@ -123530,10 +123627,6 @@ var DOCTOR_SECTIONS = [
|
|
|
123530
123627
|
"frontdoor",
|
|
123531
123628
|
"models"
|
|
123532
123629
|
];
|
|
123533
|
-
function joinNames(names) {
|
|
123534
|
-
const last = names.at(-1);
|
|
123535
|
-
return names.length < 2 || last === void 0 ? names.join("") : `${names.slice(0, -1).join(", ")} and ${last}`;
|
|
123536
|
-
}
|
|
123537
123630
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
123538
123631
|
if (status.status !== "shadowed") {
|
|
123539
123632
|
return status;
|
|
@@ -123846,6 +123939,7 @@ function runDoctor(params) {
|
|
|
123846
123939
|
}
|
|
123847
123940
|
const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
|
|
123848
123941
|
const pools = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.pools ?? {} : {};
|
|
123942
|
+
const accountByIdentity = new Map(params.identities.flatMap((entry) => validIdentityNames.has(entry.name) && entry.account !== void 0 ? [[entry.name, entry.account]] : []));
|
|
123849
123943
|
for (const [poolName, pool] of Object.entries(pools)) {
|
|
123850
123944
|
const missing = pool.identities.filter((member) => poolNameOf(poolMemberIdentity(member)) === void 0 && !validIdentityNames.has(poolMemberIdentity(member)));
|
|
123851
123945
|
const undefinedPools = pool.identities.flatMap((member) => {
|
|
@@ -123861,6 +123955,9 @@ function runDoctor(params) {
|
|
|
123861
123955
|
];
|
|
123862
123956
|
push("pool", "fail", `Pool "${poolName}" names ${problems.join(" and ")}.`, poolName);
|
|
123863
123957
|
}
|
|
123958
|
+
for (const shared of sharedLoginMembers(pool.identities.map(poolMemberIdentity), (identityName) => accountByIdentity.get(identityName))) {
|
|
123959
|
+
push("pool", "warn", describeSharedLoginMembers(poolName, shared), poolName);
|
|
123960
|
+
}
|
|
123864
123961
|
}
|
|
123865
123962
|
const reportedCycles = /* @__PURE__ */ new Set();
|
|
123866
123963
|
for (const poolName of Object.keys(pools).sort()) {
|
|
@@ -133188,6 +133285,7 @@ init_providersStore();
|
|
|
133188
133285
|
// src/frontdoor/configSchemas.ts
|
|
133189
133286
|
init_zod();
|
|
133190
133287
|
init_schema();
|
|
133288
|
+
init_names();
|
|
133191
133289
|
init_statusline();
|
|
133192
133290
|
var RemovalConfirmationSchema = external_exports.boolean();
|
|
133193
133291
|
var CredentialWriteSchema = (targets) => external_exports.strictObject({
|
|
@@ -133213,6 +133311,7 @@ var mutationOutput = (kind, action) => external_exports.strictObject({ action: e
|
|
|
133213
133311
|
var storedMutationOutput = (kind, action, value2) => external_exports.strictObject({ action: external_exports.literal(action), kind: external_exports.literal(kind), name: external_exports.string(), value: value2 });
|
|
133214
133312
|
var IdentityValueSchema = external_exports.strictObject({
|
|
133215
133313
|
name: external_exports.string(),
|
|
133314
|
+
label: external_exports.string().optional(),
|
|
133216
133315
|
defaultConfigProfile: external_exports.string().optional(),
|
|
133217
133316
|
provider: external_exports.string().optional(),
|
|
133218
133317
|
allowAmbientCredential: external_exports.boolean(),
|
|
@@ -133233,6 +133332,8 @@ var ConfigNameInputSchema = external_exports.strictObject({ name: external_expor
|
|
|
133233
133332
|
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
133234
133333
|
var ConfigIdentitySetInputSchema = external_exports.strictObject({
|
|
133235
133334
|
name: external_exports.string().min(1),
|
|
133335
|
+
/** The identity's display label; `false` clears it. */
|
|
133336
|
+
label: external_exports.union([IdentityLabelSchema, external_exports.literal(false)]).optional(),
|
|
133236
133337
|
defaultConfigProfile: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
|
|
133237
133338
|
/** The provider the identity exists for; `false` clears it. */
|
|
133238
133339
|
provider: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
|
|
@@ -133379,6 +133480,7 @@ function identityValue(name, paths) {
|
|
|
133379
133480
|
}
|
|
133380
133481
|
return {
|
|
133381
133482
|
name: identity.name,
|
|
133483
|
+
...identity.label === void 0 ? {} : { label: identity.label },
|
|
133382
133484
|
...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
|
|
133383
133485
|
...identity.provider === void 0 ? {} : { provider: identity.provider },
|
|
133384
133486
|
allowAmbientCredential: identity.allowAmbientCredential,
|
|
@@ -133413,9 +133515,9 @@ function createConfigApiRouter(deps) {
|
|
|
133413
133515
|
return { action: "created", kind: "identity", name: input2.name, value: identityValue(input2.name, paths) };
|
|
133414
133516
|
})
|
|
133415
133517
|
),
|
|
133416
|
-
set: route("/rest/config/identity/set", "Update an identity's default profile, provider, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
133518
|
+
set: route("/rest/config/identity/set", "Update an identity's label, default profile, provider, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
133417
133519
|
({ input: input2 }) => guarded(() => {
|
|
133418
|
-
requireChange(input2.defaultConfigProfile !== void 0 || input2.provider !== void 0 || input2.allowAmbientCredential !== void 0 || input2.credential !== void 0 || input2.anchors !== void 0, "defaultConfigProfile, provider, allowAmbientCredential, credential or anchors");
|
|
133520
|
+
requireChange(input2.label !== void 0 || input2.defaultConfigProfile !== void 0 || input2.provider !== void 0 || input2.allowAmbientCredential !== void 0 || input2.credential !== void 0 || input2.anchors !== void 0, "label, defaultConfigProfile, provider, allowAmbientCredential, credential or anchors");
|
|
133419
133521
|
if (!identityExists(paths, input2.name)) {
|
|
133420
133522
|
throw new IdentityNotFoundError(input2.name);
|
|
133421
133523
|
}
|
|
@@ -133425,6 +133527,9 @@ function createConfigApiRouter(deps) {
|
|
|
133425
133527
|
if (typeof input2.provider === "string") {
|
|
133426
133528
|
requireProviderExists(paths, input2.provider);
|
|
133427
133529
|
}
|
|
133530
|
+
if (input2.label !== void 0) {
|
|
133531
|
+
setIdentityLabel(paths, input2.name, input2.label === false ? void 0 : input2.label);
|
|
133532
|
+
}
|
|
133428
133533
|
if (input2.defaultConfigProfile !== void 0) {
|
|
133429
133534
|
setDefaultConfigProfile(paths, input2.name, input2.defaultConfigProfile === false ? void 0 : input2.defaultConfigProfile);
|
|
133430
133535
|
}
|
|
@@ -140963,6 +141068,7 @@ function enrichStatuslinePayload(params) {
|
|
|
140963
141068
|
const account = clientEmail === void 0 ? params.account : void 0;
|
|
140964
141069
|
let summary = {
|
|
140965
141070
|
identity,
|
|
141071
|
+
identityLabel: params.identityLabel,
|
|
140966
141072
|
provider: params.env.AGENT_SHIM_PROVIDER === void 0 || params.env.AGENT_SHIM_PROVIDER === "" ? void 0 : params.env.AGENT_SHIM_PROVIDER,
|
|
140967
141073
|
providerAccountEmail: void 0,
|
|
140968
141074
|
providerAccountSub: void 0,
|
|
@@ -142285,7 +142391,13 @@ function headroomSegment({ summary, t: t10 }) {
|
|
|
142285
142391
|
|
|
142286
142392
|
// src/statusline/elements/header/identity.ts
|
|
142287
142393
|
function identitySegment({ summary }) {
|
|
142288
|
-
if (summary.identity
|
|
142394
|
+
if (summary.identity === void 0) {
|
|
142395
|
+
return void 0;
|
|
142396
|
+
}
|
|
142397
|
+
if (summary.identityLabel !== void 0) {
|
|
142398
|
+
return `${summary.identity} (${summary.identityLabel})`;
|
|
142399
|
+
}
|
|
142400
|
+
if (summary.provider !== void 0 && summary.identity !== summary.providerAccountEmail && summary.identity !== summary.loginAccountEmail) {
|
|
142289
142401
|
return summary.identity;
|
|
142290
142402
|
}
|
|
142291
142403
|
return void 0;
|
|
@@ -145319,7 +145431,13 @@ function registerStatuslineCommand(program2, deps) {
|
|
|
145319
145431
|
const identity = identityOf(process.env);
|
|
145320
145432
|
let snapshot;
|
|
145321
145433
|
let account;
|
|
145434
|
+
let identityLabel;
|
|
145322
145435
|
if (identity !== void 0) {
|
|
145436
|
+
try {
|
|
145437
|
+
identityLabel = readIdentity(deps.paths, identity)?.label;
|
|
145438
|
+
} catch {
|
|
145439
|
+
identityLabel = void 0;
|
|
145440
|
+
}
|
|
145323
145441
|
try {
|
|
145324
145442
|
snapshot = readUsageSnapshot(realFarmFs, deps.paths.usageSnapshotsDir, identity);
|
|
145325
145443
|
} catch {
|
|
@@ -145371,7 +145489,7 @@ function registerStatuslineCommand(program2, deps) {
|
|
|
145371
145489
|
}
|
|
145372
145490
|
}
|
|
145373
145491
|
const clientPayload = parseClientPayload(payload);
|
|
145374
|
-
const enrichParams = { payload, env: process.env, snapshot, account, providerName, nowMs, headroom, routedTarget, ...modelChoice === void 0 ? {} : { modelChoice } };
|
|
145492
|
+
const enrichParams = { payload, env: process.env, identityLabel, snapshot, account, providerName, nowMs, headroom, routedTarget, ...modelChoice === void 0 ? {} : { modelChoice } };
|
|
145375
145493
|
const renderer = process.env.AGENT_SHIM_STATUSLINE_CMD;
|
|
145376
145494
|
if (renderer !== void 0 && renderer !== "") {
|
|
145377
145495
|
const child = (0, import_node_child_process9.spawn)("/bin/sh", ["-c", renderer], { stdio: ["pipe", "inherit", "inherit"] });
|
|
@@ -156376,6 +156494,7 @@ init_schema();
|
|
|
156376
156494
|
init_realPorts();
|
|
156377
156495
|
init_candidateText();
|
|
156378
156496
|
init_preflight();
|
|
156497
|
+
init_identityAccounts();
|
|
156379
156498
|
function formatPoolPick(report, nowMs) {
|
|
156380
156499
|
const head = report.pick === void 0 ? `Pool ${report.pool}: every member is refused right now${report.earliestReturn === void 0 ? "" : `; ${report.earliestReturn.identity} returns at ${report.earliestReturn.at} (in ${formatAge(Date.parse(report.earliestReturn.at) - nowMs)})`}` : `Pool ${report.pool}: a launch from ${report.directory} would run as ${report.pick}`;
|
|
156381
156500
|
const rows = report.candidates.map((candidate, index) => {
|
|
@@ -156384,6 +156503,11 @@ function formatPoolPick(report, nowMs) {
|
|
|
156384
156503
|
});
|
|
156385
156504
|
return [head, ...rows, ...report.missing.map((name) => ` (skipped: ${name} is not an identity)`), ...report.stickyProblem === void 0 ? [] : [`Note: ${report.stickyProblem}; the last-pick record was ignored.`]];
|
|
156386
156505
|
}
|
|
156506
|
+
function warnSharedLogins(paths, poolName, members2) {
|
|
156507
|
+
for (const shared of sharedLoginMembers(members2, (identity) => readIdentityAccount(realFsPort, paths.identitiesDir, identity)?.account)) {
|
|
156508
|
+
console.error(`agent-shim: warning: ${describeSharedLoginMembers(poolName, shared)}`);
|
|
156509
|
+
}
|
|
156510
|
+
}
|
|
156387
156511
|
function policyNotes(entry) {
|
|
156388
156512
|
const notes = [
|
|
156389
156513
|
...entry?.preference === void 0 ? [] : [`preference: ${entry.preference}`],
|
|
@@ -156416,6 +156540,7 @@ function registerPoolCommand(program2, deps) {
|
|
|
156416
156540
|
reportMutation(options.json, { action: "created", kind: "pool", name, value: created }, () => {
|
|
156417
156541
|
console.log(`Created pool "${name}" with ${members2.join(", ")}.`);
|
|
156418
156542
|
});
|
|
156543
|
+
warnSharedLogins(paths, name, created.identities.map(poolMemberIdentity));
|
|
156419
156544
|
}),
|
|
156420
156545
|
["agent-shim pool add subs --identity work --identity personal", "agent-shim pool add client --identity client-main --identity spare --preference listed"]
|
|
156421
156546
|
);
|
|
@@ -156433,6 +156558,7 @@ function registerPoolCommand(program2, deps) {
|
|
|
156433
156558
|
reportMutation(options.json, { action: "updated", kind: "pool", name, value: updated }, () => {
|
|
156434
156559
|
console.log(`Pool "${name}" now has ${updated.identities.map(poolMemberIdentity).join(", ")}.`);
|
|
156435
156560
|
});
|
|
156561
|
+
warnSharedLogins(paths, name, updated.identities.map(poolMemberIdentity));
|
|
156436
156562
|
}),
|
|
156437
156563
|
["agent-shim pool set subs --identity work --identity personal --identity spare", "agent-shim pool set subs --preference listed", "agent-shim pool set subs --resume-on-limit --compact-before-limit --compact-at-utilisation 85"]
|
|
156438
156564
|
);
|
|
@@ -157481,6 +157607,7 @@ var import_node_path70 = __toESM(require("node:path"), 1);
|
|
|
157481
157607
|
init_commandDeps();
|
|
157482
157608
|
init_realPorts();
|
|
157483
157609
|
init_account();
|
|
157610
|
+
init_accountDescription();
|
|
157484
157611
|
init_signIn();
|
|
157485
157612
|
init_resets();
|
|
157486
157613
|
init_read();
|
|
@@ -157839,6 +157966,7 @@ function promptsIdentityPicker(prompts) {
|
|
|
157839
157966
|
// src/launcher/runPicker.ts
|
|
157840
157967
|
init_cliError();
|
|
157841
157968
|
init_schema();
|
|
157969
|
+
init_identityAccounts();
|
|
157842
157970
|
init_account();
|
|
157843
157971
|
init_candidateText();
|
|
157844
157972
|
init_pick();
|