agent-shim 7.11.0 → 7.12.1
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 +23 -23
- package/dist/cli.cjs +115 -57
- package/dist/types/cli/commandDeps.d.ts +11 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,47 +82,47 @@ The full mechanics, including the credential block, the merge algorithm, conditi
|
|
|
82
82
|
```
|
|
83
83
|
agent-shim <noun> <verb> [name] [options] # nouns: identity, profile, pool, provider, rule
|
|
84
84
|
|
|
85
|
-
agent-shim identity add <name>
|
|
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] [--[no-]allow-ambient-credential]
|
|
89
|
-
agent-shim identity set <name> [--credential <source>]... [--credential-target <bearer|apiKey|oauthToken>] [--no-credential]
|
|
90
|
-
agent-shim identity remove <name> [--yes]
|
|
91
|
-
agent-shim identity use <name>
|
|
88
|
+
agent-shim identity set <name> [--default-profile <profile> | --no-default-profile] [--[no-]allow-ambient-credential] [--json]
|
|
89
|
+
agent-shim identity set <name> [--credential <source>]... [--credential-target <bearer|apiKey|oauthToken>] [--no-credential] [--json]
|
|
90
|
+
agent-shim identity remove <name> [--yes] [--json]
|
|
91
|
+
agent-shim identity use <name> [--json]
|
|
92
92
|
agent-shim @<name> # shorthand for `identity use <name>`
|
|
93
93
|
agent-shim identity resolve-conflicts <name> # interactively resolve a retained superseded farm's conflicts
|
|
94
94
|
|
|
95
|
-
agent-shim profile add [name] [--extends <profile>]... [--description <text>] # interactive with no options on a terminal
|
|
96
|
-
agent-shim profile set <name> [--category <category>=<bool>]... [--entry <category>/<path>=<bool>]...
|
|
97
|
-
agent-shim profile set <name> [--extends <profile>]... [--no-extends] [--description <text> | --no-description]
|
|
98
|
-
agent-shim profile set <name> [--[no-]launch-skip-permissions] [--[no-]launch-remote-control] [--[no-]launch-headroom] [--[no-]launch-track-usage]
|
|
99
|
-
agent-shim profile set <name> [--launch-provider <provider> | --no-launch-provider]
|
|
95
|
+
agent-shim profile add [name] [--extends <profile>]... [--description <text>] # interactive with no options on a terminal [--json]
|
|
96
|
+
agent-shim profile set <name> [--category <category>=<bool>]... [--entry <category>/<path>=<bool>]... [--json]
|
|
97
|
+
agent-shim profile set <name> [--extends <profile>]... [--no-extends] [--description <text> | --no-description] [--json]
|
|
98
|
+
agent-shim profile set <name> [--[no-]launch-skip-permissions] [--[no-]launch-remote-control] [--[no-]launch-headroom] [--[no-]launch-track-usage] [--json]
|
|
99
|
+
agent-shim profile set <name> [--launch-provider <provider> | --no-launch-provider] [--json]
|
|
100
100
|
agent-shim profile list [--json]
|
|
101
101
|
agent-shim profile show <name> [--json]
|
|
102
|
-
agent-shim profile remove <name> [--yes]
|
|
103
|
-
agent-shim profile use <name> # the global default configuration profile
|
|
102
|
+
agent-shim profile remove <name> [--yes] [--json]
|
|
103
|
+
agent-shim profile use <name> # the global default configuration profile [--json]
|
|
104
104
|
|
|
105
|
-
agent-shim pool add <name> --identity <identity>...
|
|
106
|
-
agent-shim pool set <name> --identity <identity>...
|
|
105
|
+
agent-shim pool add <name> --identity <identity>... [--json]
|
|
106
|
+
agent-shim pool set <name> --identity <identity>... [--json]
|
|
107
107
|
agent-shim pool list [--json]
|
|
108
108
|
agent-shim pool show <name> [--json]
|
|
109
|
-
agent-shim pool remove <name> [--yes]
|
|
110
|
-
agent-shim pool use <name>
|
|
109
|
+
agent-shim pool remove <name> [--yes] [--json]
|
|
110
|
+
agent-shim pool use <name> [--json]
|
|
111
111
|
agent-shim pool pick <name> [--json]
|
|
112
112
|
|
|
113
|
-
agent-shim provider add <name> --display-name <name> (--base-url <url> | --kind codex) (--credential <source>)... [--credential-target <bearer|apiKey>] [--env KEY=VALUE]...
|
|
113
|
+
agent-shim provider add <name> --display-name <name> (--base-url <url> | --kind codex) (--credential <source>)... [--credential-target <bearer|apiKey>] [--env KEY=VALUE]... [--json]
|
|
114
114
|
[--codex-default-model <model>] [--codex-model <tier=model>]... [--codex-effort <none|low|medium|high>]
|
|
115
|
-
agent-shim provider set <name> [--display-name <name>] ([--base-url <url>] | --kind codex) [--credential <source>]... [--credential-target <bearer|apiKey>] [--env KEY=VALUE]... [--unset-env KEY]...
|
|
115
|
+
agent-shim provider set <name> [--display-name <name>] ([--base-url <url>] | --kind codex) [--credential <source>]... [--credential-target <bearer|apiKey>] [--env KEY=VALUE]... [--unset-env KEY]... [--json]
|
|
116
116
|
[--codex-default-model <model>] [--codex-model <tier=model>]... [--codex-effort <none|low|medium|high>]
|
|
117
117
|
agent-shim provider list [--json]
|
|
118
118
|
agent-shim provider show <name> [--json]
|
|
119
|
-
agent-shim provider remove <name> [--yes]
|
|
119
|
+
agent-shim provider remove <name> [--yes] [--json]
|
|
120
120
|
|
|
121
|
-
agent-shim rule add <path> [--config-profile <profile>] [--identity <identity>]
|
|
122
|
-
agent-shim rule set <path> [--config-profile <profile> | --no-config-profile] [--identity <identity> | --no-identity]
|
|
121
|
+
agent-shim rule add <path> [--config-profile <profile>] [--identity <identity>] [--json]
|
|
122
|
+
agent-shim rule set <path> [--config-profile <profile> | --no-config-profile] [--identity <identity> | --no-identity] [--json]
|
|
123
123
|
agent-shim rule list [--json]
|
|
124
124
|
agent-shim rule show <path> [--json]
|
|
125
|
-
agent-shim rule remove <path> [--yes]
|
|
125
|
+
agent-shim rule remove <path> [--yes] [--json]
|
|
126
126
|
|
|
127
127
|
agent-shim configure [path] [--identity <identity>]
|
|
128
128
|
agent-shim check [path] [--identity <identity>] [--json] [--strict]
|
|
@@ -144,7 +144,7 @@ agent-shim run [@<identity>] [launch flags] [claude arguments]
|
|
|
144
144
|
claude @<identity> ... # the same, once `agent-shim shim enable` has run
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
Every `list`, `show`, `check`, `doctor` and `headroom status` prints text by default and JSON with `--json`. Prompts appear only when standard input is a terminal; without one, a command that needs input fails with the option that supplies it (a `remove` needs `--yes`). Failures print as `agent-shim: <message>` and exit 1, usage errors exit 2, a selected provider or identity whose credential block yields no token exits 64, and `AGENT_SHIM_DEBUG=1` adds stack traces to unexpected errors. `agent-shim completion <bash|zsh|fish>` prints a shell completion script.
|
|
147
|
+
Every `list`, `show`, `check`, `doctor` and `headroom status` prints text by default and JSON with `--json`, and so do the mutating commands (`add`, `set`, `remove` and `use` on identities, profiles, providers, pools and rules), which print one object naming the `action`, the `kind`, the `name` and, for a creation or update, the stored `value`. Prompts appear only when standard input is a terminal; without one, a command that needs input fails with the option that supplies it (a `remove` needs `--yes`). Failures print as `agent-shim: <message>` and exit 1, usage errors exit 2, a selected provider or identity whose credential block yields no token exits 64, and `AGENT_SHIM_DEBUG=1` adds stack traces to unexpected errors. `agent-shim completion <bash|zsh|fish>` prints a shell completion script.
|
|
148
148
|
|
|
149
149
|
`agent-shim check [path]` resolves the full cascade for a directory without touching the farm, and is the primary way to answer "why is X shared or hidden here". `agent-shim doctor` audits the whole `~/.agent-shim` config graph at once: every identity, profile, `extends` chain, provider (naming the exact replacement for a file still in the format before the credential block) and directory rule, plus whether the right `agent-shim` is the one actually on `PATH`.
|
|
150
150
|
|
package/dist/cli.cjs
CHANGED
|
@@ -54858,6 +54858,13 @@ function date4(params) {
|
|
|
54858
54858
|
function printJson(value) {
|
|
54859
54859
|
console.log(JSON.stringify(value, null, 2));
|
|
54860
54860
|
}
|
|
54861
|
+
function reportMutation(json2, report, printText) {
|
|
54862
|
+
if (json2 === true) {
|
|
54863
|
+
printJson(report);
|
|
54864
|
+
} else {
|
|
54865
|
+
printText();
|
|
54866
|
+
}
|
|
54867
|
+
}
|
|
54861
54868
|
function withExamples(command, examples) {
|
|
54862
54869
|
return command.addHelpText("after", `
|
|
54863
54870
|
Examples:
|
|
@@ -60584,30 +60591,36 @@ function registerProfileCommand(program2, deps) {
|
|
|
60584
60591
|
withExamples(
|
|
60585
60592
|
profile.command("add [name]").description(
|
|
60586
60593
|
"Create a new configuration profile. Fails if one with this name already exists. With no options on a terminal, walks through choosing its categories."
|
|
60587
|
-
).option("--extends <profile>", "A profile this one extends (repeatable, in order).", collectRepeated).option("--description <text>", "A free-text description stored in the profile.").action(async (name,
|
|
60594
|
+
).option("--extends <profile>", "A profile this one extends (repeatable, in order).", collectRepeated).option("--description <text>", "A free-text description stored in the profile.").option("--json", "Print the result as JSON.").action(async (name, allOptions) => {
|
|
60595
|
+
const { json: json2, ...options } = allOptions;
|
|
60588
60596
|
const hasOptions = options.extends !== void 0 || options.description !== void 0;
|
|
60589
60597
|
if (!hasOptions && deps.isInteractive()) {
|
|
60590
60598
|
const result = await runProfileWizard(deps.prompts, name === void 0 ? { paths } : { paths, createName: name });
|
|
60591
60599
|
if (result === void 0) {
|
|
60592
60600
|
throw new PromptCancelledError();
|
|
60593
60601
|
}
|
|
60594
|
-
|
|
60602
|
+
reportMutation(json2, { action: "created", kind: "profile", name: result.name, value: readProfile(paths, result.name) }, () => {
|
|
60603
|
+
console.log(`Created configuration profile "${result.name}".`);
|
|
60604
|
+
});
|
|
60595
60605
|
return;
|
|
60596
60606
|
}
|
|
60597
60607
|
if (name === void 0) {
|
|
60598
60608
|
throw new UsageError("missing required argument 'name' (standard input is not a terminal, so there is nothing to prompt on).");
|
|
60599
60609
|
}
|
|
60600
|
-
createProfile(paths, name, options.extends, options.description);
|
|
60601
|
-
|
|
60610
|
+
const created = createProfile(paths, name, options.extends, options.description);
|
|
60611
|
+
reportMutation(json2, { action: "created", kind: "profile", name, value: created }, () => {
|
|
60612
|
+
console.log(`Created configuration profile "${name}".`);
|
|
60613
|
+
});
|
|
60602
60614
|
}),
|
|
60603
60615
|
["agent-shim profile add client-acme", "agent-shim profile add client-acme --extends work-default --extends strict"]
|
|
60604
60616
|
);
|
|
60605
60617
|
withExamples(
|
|
60606
60618
|
profile.command("set <name>").description(
|
|
60607
60619
|
"Update a configuration profile's categories, entries, extends list, description or launch settings. With no options on a terminal, walks through its categories."
|
|
60608
|
-
).option("--category <category=bool>", "Share (true) or hide (false) a whole category (repeatable).", collectBoolPair).option("--entry <path=bool>", "Share (true) or hide (false) one <category>/<path> entry (repeatable).", collectBoolPair).option("--extends <profile>", "Replace the extends list with these profiles (repeatable, in order).", collectRepeated).option("--no-extends", "Clear the extends list.").option("--description <text>", "Replace the description.").option("--no-description", "Clear the description.").option("--launch-skip-permissions", "Launches under this profile skip permission prompts.").option("--no-launch-skip-permissions", "Launches under this profile keep permission prompts.").option("--launch-remote-control", "Launches under this profile enable Remote Control.").option("--no-launch-remote-control", "Launches under this profile leave Remote Control off.").option("--launch-headroom", "Launches under this profile route through headroom.").option("--no-launch-headroom", "Launches under this profile route direct.").option("--launch-track-usage", "Launches under this profile route through the front door so their requests and quota are recorded, with no headroom needed.").option("--no-launch-track-usage", "Launches under this profile are not recorded unless a provider or headroom routes them anyway.").option("--launch-provider <provider>", "Launches under this profile route through this provider.").option("--no-launch-provider", "Clear this profile's provider selection.").action(async (name,
|
|
60620
|
+
).option("--category <category=bool>", "Share (true) or hide (false) a whole category (repeatable).", collectBoolPair).option("--entry <path=bool>", "Share (true) or hide (false) one <category>/<path> entry (repeatable).", collectBoolPair).option("--extends <profile>", "Replace the extends list with these profiles (repeatable, in order).", collectRepeated).option("--no-extends", "Clear the extends list.").option("--description <text>", "Replace the description.").option("--no-description", "Clear the description.").option("--launch-skip-permissions", "Launches under this profile skip permission prompts.").option("--no-launch-skip-permissions", "Launches under this profile keep permission prompts.").option("--launch-remote-control", "Launches under this profile enable Remote Control.").option("--no-launch-remote-control", "Launches under this profile leave Remote Control off.").option("--launch-headroom", "Launches under this profile route through headroom.").option("--no-launch-headroom", "Launches under this profile route direct.").option("--launch-track-usage", "Launches under this profile route through the front door so their requests and quota are recorded, with no headroom needed.").option("--no-launch-track-usage", "Launches under this profile are not recorded unless a provider or headroom routes them anyway.").option("--launch-provider <provider>", "Launches under this profile route through this provider.").option("--no-launch-provider", "Clear this profile's provider selection.").option("--json", "Print the result as JSON.").action(async (name, allOptions) => {
|
|
60621
|
+
const { json: json2, ...options } = allOptions;
|
|
60609
60622
|
requireProfileExists(paths, name);
|
|
60610
|
-
if (Object.
|
|
60623
|
+
if (Object.entries(allOptions).every(([key, value]) => key === "json" || value === void 0)) {
|
|
60611
60624
|
if (!deps.isInteractive()) {
|
|
60612
60625
|
throw new UsageError(
|
|
60613
60626
|
"Nothing to change: pass --category, --entry, --extends, --description or a --launch-* option (standard input is not a terminal, so there is nothing to prompt on)."
|
|
@@ -60619,7 +60632,9 @@ function registerProfileCommand(program2, deps) {
|
|
|
60619
60632
|
} else {
|
|
60620
60633
|
applyProfileSet(paths, name, options);
|
|
60621
60634
|
}
|
|
60622
|
-
|
|
60635
|
+
reportMutation(json2, { action: "updated", kind: "profile", name, value: readProfile(paths, name) }, () => {
|
|
60636
|
+
console.log(`Updated configuration profile "${name}".`);
|
|
60637
|
+
});
|
|
60623
60638
|
}),
|
|
60624
60639
|
[
|
|
60625
60640
|
"agent-shim profile set client-acme --category history=false --category knowledge=true",
|
|
@@ -60675,19 +60690,23 @@ function registerProfileCommand(program2, deps) {
|
|
|
60675
60690
|
["agent-shim profile show client-acme", "agent-shim profile show client-acme --json"]
|
|
60676
60691
|
);
|
|
60677
60692
|
withExamples(
|
|
60678
|
-
profile.command("remove <name>").description("Delete a configuration profile's file. References to it by name are left for `agent-shim doctor` to report.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (name, options) => {
|
|
60693
|
+
profile.command("remove <name>").description("Delete a configuration profile's file. References to it by name are left for `agent-shim doctor` to report.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").option("--json", "Print the result as JSON.").action(async (name, options) => {
|
|
60679
60694
|
requireProfileExists(paths, name);
|
|
60680
60695
|
await confirmRemoval(deps, options.yes, `configuration profile "${name}"`);
|
|
60681
60696
|
removeProfile(paths, name);
|
|
60682
|
-
|
|
60697
|
+
reportMutation(options.json, { action: "removed", kind: "profile", name }, () => {
|
|
60698
|
+
console.log(`Removed configuration profile "${name}".`);
|
|
60699
|
+
});
|
|
60683
60700
|
}),
|
|
60684
60701
|
["agent-shim profile remove client-acme --yes"]
|
|
60685
60702
|
);
|
|
60686
60703
|
withExamples(
|
|
60687
|
-
profile.command("use <name>").description("Make a configuration profile the global default, used when no directory rule or identity selects one.").action(async (name) => {
|
|
60704
|
+
profile.command("use <name>").description("Make a configuration profile the global default, used when no directory rule or identity selects one.").option("--json", "Print the result as JSON.").action(async (name, options) => {
|
|
60688
60705
|
await ensureProfileExists(deps, name);
|
|
60689
60706
|
setGlobalDefaultProfile(paths, name);
|
|
60690
|
-
|
|
60707
|
+
reportMutation(options.json, { action: "selected", kind: "profile", name }, () => {
|
|
60708
|
+
console.log(`Global default configuration profile is now "${name}".`);
|
|
60709
|
+
});
|
|
60691
60710
|
}),
|
|
60692
60711
|
["agent-shim profile use work-default"]
|
|
60693
60712
|
);
|
|
@@ -60732,7 +60751,7 @@ async function runIdentityWizard(prompts, paths, name, options = {}) {
|
|
|
60732
60751
|
prompts.outro(`Identity "${name}" is set up and active.`);
|
|
60733
60752
|
return true;
|
|
60734
60753
|
}
|
|
60735
|
-
async function selectIdentity(deps, name) {
|
|
60754
|
+
async function selectIdentity(deps, name, json2) {
|
|
60736
60755
|
if (poolNameOf(name) !== void 0 || identityExists(deps.paths, name)) {
|
|
60737
60756
|
useIdentity(deps.paths, name);
|
|
60738
60757
|
} else if (deps.isInteractive()) {
|
|
@@ -60742,7 +60761,9 @@ async function selectIdentity(deps, name) {
|
|
|
60742
60761
|
} else {
|
|
60743
60762
|
throw new IdentityNotFoundError(name);
|
|
60744
60763
|
}
|
|
60745
|
-
|
|
60764
|
+
reportMutation(json2, { action: "selected", kind: "identity", name }, () => {
|
|
60765
|
+
console.log(`Active identity is now "${name}".`);
|
|
60766
|
+
});
|
|
60746
60767
|
}
|
|
60747
60768
|
async function tryRunAtIdentityShortcut(deps, argv) {
|
|
60748
60769
|
if (argv.length !== 1) {
|
|
@@ -60784,9 +60805,11 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60784
60805
|
["agent-shim identity add work", "agent-shim identity list"]
|
|
60785
60806
|
);
|
|
60786
60807
|
withExamples(
|
|
60787
|
-
identity.command("add <name>").description("Create a new identity. Fails if one with this name already exists.").action((name) => {
|
|
60788
|
-
addIdentity(paths, name);
|
|
60789
|
-
|
|
60808
|
+
identity.command("add <name>").description("Create a new identity. Fails if one with this name already exists.").option("--json", "Print the result as JSON.").action((name, options) => {
|
|
60809
|
+
const created = addIdentity(paths, name);
|
|
60810
|
+
reportMutation(options.json, { action: "created", kind: "identity", name, value: created }, () => {
|
|
60811
|
+
console.log(`Created identity "${name}".`);
|
|
60812
|
+
});
|
|
60790
60813
|
}),
|
|
60791
60814
|
["agent-shim identity add work"]
|
|
60792
60815
|
);
|
|
@@ -60833,7 +60856,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60833
60856
|
}),
|
|
60834
60857
|
["agent-shim identity show work", "agent-shim identity show work --json"]
|
|
60835
60858
|
);
|
|
60836
|
-
const identitySet = identity.command("set <name>").description("Update an identity's settings.").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("--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(
|
|
60859
|
+
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("--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(
|
|
60837
60860
|
"--credential <source>",
|
|
60838
60861
|
`Authenticate this identity from a token instead of its stored login, replacing any existing sources (repeatable, in the order tried): ${CREDENTIAL_SOURCE_SYNTAX}.`,
|
|
60839
60862
|
collectCredentialSource
|
|
@@ -60845,8 +60868,9 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60845
60868
|
);
|
|
60846
60869
|
addCredentialCacheOptions(identitySet);
|
|
60847
60870
|
withExamples(
|
|
60848
|
-
identitySet.action(async (name,
|
|
60849
|
-
|
|
60871
|
+
identitySet.action(async (name, allOptions) => {
|
|
60872
|
+
const { json: json2, ...options } = allOptions;
|
|
60873
|
+
if (Object.entries(allOptions).every(([key, value]) => key === "json" || value === void 0)) {
|
|
60850
60874
|
throw new UsageError(
|
|
60851
60875
|
"Nothing to change: pass --default-profile, --no-default-profile, --allow-ambient-credential, --no-allow-ambient-credential, --credential, --no-credential, --credential-target or a --credential-cache option."
|
|
60852
60876
|
);
|
|
@@ -60854,25 +60878,24 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60854
60878
|
if (!identityExists(paths, name)) {
|
|
60855
60879
|
throw new IdentityNotFoundError(name);
|
|
60856
60880
|
}
|
|
60881
|
+
const messages = [];
|
|
60857
60882
|
if (options.defaultProfile !== void 0) {
|
|
60858
60883
|
const profileName = options.defaultProfile === false ? void 0 : options.defaultProfile;
|
|
60859
60884
|
if (profileName !== void 0) {
|
|
60860
60885
|
await ensureProfileExists(deps, profileName);
|
|
60861
60886
|
}
|
|
60862
60887
|
setDefaultConfigProfile(paths, name, profileName);
|
|
60863
|
-
|
|
60888
|
+
messages.push(
|
|
60864
60889
|
profileName === void 0 ? `Identity "${name}" no longer has a default configuration profile.` : `Identity "${name}" now defaults to configuration profile "${profileName}".`
|
|
60865
60890
|
);
|
|
60866
60891
|
}
|
|
60867
60892
|
if (options.allowAmbientCredential !== void 0) {
|
|
60868
60893
|
setAllowAmbientCredential(paths, name, options.allowAmbientCredential);
|
|
60869
|
-
|
|
60870
|
-
`Identity "${name}" ${options.allowAmbientCredential ? "now allows" : "no longer allows"} an ambient credential.`
|
|
60871
|
-
);
|
|
60894
|
+
messages.push(`Identity "${name}" ${options.allowAmbientCredential ? "now allows" : "no longer allows"} an ambient credential.`);
|
|
60872
60895
|
}
|
|
60873
60896
|
if (options.credential === false) {
|
|
60874
60897
|
setIdentityCredential(paths, name, false);
|
|
60875
|
-
|
|
60898
|
+
messages.push(`Identity "${name}" no longer has a credential and uses its stored login.`);
|
|
60876
60899
|
} else if (options.credential !== void 0 || options.credentialTarget !== void 0 || cacheChange(options, void 0) !== void 0) {
|
|
60877
60900
|
const cache = cacheChange(options, readIdentity(paths, name)?.credential?.cache);
|
|
60878
60901
|
const updated = setIdentityCredential(paths, name, {
|
|
@@ -60881,9 +60904,14 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60881
60904
|
...cache === void 0 ? {} : { cache }
|
|
60882
60905
|
});
|
|
60883
60906
|
if (updated.credential !== void 0) {
|
|
60884
|
-
|
|
60907
|
+
messages.push(`Identity "${name}" now authenticates with credential ${describeCredential(updated.credential)}.`);
|
|
60885
60908
|
}
|
|
60886
60909
|
}
|
|
60910
|
+
reportMutation(json2, { action: "updated", kind: "identity", name, value: readIdentity(paths, name) }, () => {
|
|
60911
|
+
for (const message of messages) {
|
|
60912
|
+
console.log(message);
|
|
60913
|
+
}
|
|
60914
|
+
});
|
|
60887
60915
|
}),
|
|
60888
60916
|
[
|
|
60889
60917
|
"agent-shim identity set work --default-profile client-acme",
|
|
@@ -60895,19 +60923,21 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60895
60923
|
withExamples(
|
|
60896
60924
|
identity.command("remove <name>").description(
|
|
60897
60925
|
"Delete an identity and its directory, including its credentials and anything it does not share with ~/.claude. Shared data in ~/.claude is kept."
|
|
60898
|
-
).option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (name, options) => {
|
|
60926
|
+
).option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").option("--json", "Print the result as JSON.").action(async (name, options) => {
|
|
60899
60927
|
if (!identityExists(paths, name)) {
|
|
60900
60928
|
throw new IdentityNotFoundError(name);
|
|
60901
60929
|
}
|
|
60902
60930
|
await confirmRemoval(deps, options.yes, `identity "${name}" and its directory ${import_node_path20.default.join(paths.identitiesDir, name)}`);
|
|
60903
60931
|
removeIdentity(paths, name);
|
|
60904
|
-
|
|
60932
|
+
reportMutation(options.json, { action: "removed", kind: "identity", name }, () => {
|
|
60933
|
+
console.log(`Removed identity "${name}".`);
|
|
60934
|
+
});
|
|
60905
60935
|
}),
|
|
60906
60936
|
["agent-shim identity remove old-client --yes"]
|
|
60907
60937
|
);
|
|
60908
60938
|
withExamples(
|
|
60909
|
-
identity.command("use <name>").description("Select the active identity, used by every launch that names none. Offers to create it on a terminal if it does not exist.").action(async (name) => {
|
|
60910
|
-
await selectIdentity(deps, name);
|
|
60939
|
+
identity.command("use <name>").description("Select the active identity, used by every launch that names none. Offers to create it on a terminal if it does not exist.").option("--json", "Print the result as JSON.").action(async (name, options) => {
|
|
60940
|
+
await selectIdentity(deps, name, options.json);
|
|
60911
60941
|
}),
|
|
60912
60942
|
["agent-shim identity use work", "agent-shim @work"]
|
|
60913
60943
|
);
|
|
@@ -60955,7 +60985,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60955
60985
|
// package.json
|
|
60956
60986
|
var package_default = {
|
|
60957
60987
|
name: "agent-shim",
|
|
60958
|
-
version: "7.
|
|
60988
|
+
version: "7.12.1",
|
|
60959
60989
|
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.",
|
|
60960
60990
|
license: "MIT",
|
|
60961
60991
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -65183,7 +65213,10 @@ async function forwardThroughHeadroom(request6, response, target) {
|
|
|
65183
65213
|
if (!request6.signal.aborted) {
|
|
65184
65214
|
response.end();
|
|
65185
65215
|
}
|
|
65186
|
-
} catch {
|
|
65216
|
+
} catch (error62) {
|
|
65217
|
+
if (!request6.signal.aborted) {
|
|
65218
|
+
target.log(`front door: headroom hop to 127.0.0.1:${String(port)} ended mid-stream (${request6.method} ${new URL(request6.url, "http://127.0.0.1").pathname}): ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65219
|
+
}
|
|
65187
65220
|
response.destroy();
|
|
65188
65221
|
}
|
|
65189
65222
|
resolve(void 0);
|
|
@@ -65192,7 +65225,9 @@ async function forwardThroughHeadroom(request6, response, target) {
|
|
|
65192
65225
|
};
|
|
65193
65226
|
const hop = http3.request({ host: "127.0.0.1", port, method: request6.method, path: request6.url, headers, agent: HOP_AGENT }, onUpstreamResponse);
|
|
65194
65227
|
hop.on("error", (error62) => {
|
|
65195
|
-
|
|
65228
|
+
const phase = response.headersSent ? "mid-stream" : "before the response started";
|
|
65229
|
+
const code = "code" in error62 && typeof error62.code === "string" ? ` ${error62.code}` : "";
|
|
65230
|
+
target.log(`front door: headroom hop to 127.0.0.1:${String(port)} failed (${request6.method} ${new URL(request6.url, "http://127.0.0.1").pathname}, ${phase}): ${error62.message}${code}`);
|
|
65196
65231
|
if (!response.headersSent) {
|
|
65197
65232
|
response.start(HTTP_BAD_GATEWAY2, { "Content-Type": "application/json" });
|
|
65198
65233
|
void response.write(JSON.stringify({ type: "error", error: { type: "api_error", message: `agent-shim front door: the headroom daemon is unreachable (${error62.message})` } })).then(() => {
|
|
@@ -68598,20 +68633,24 @@ function registerPoolCommand(program2, deps) {
|
|
|
68598
68633
|
["agent-shim pool add subs --identity work --identity personal", "agent-shim pool pick subs"]
|
|
68599
68634
|
);
|
|
68600
68635
|
withExamples(
|
|
68601
|
-
pool.command("add <name>").description("Define a pool. Fails if one with this name already exists.").option("--identity <name>", "A member identity (repeatable).", collectRepeated).action((name, options) => {
|
|
68636
|
+
pool.command("add <name>").description("Define a pool. Fails if one with this name already exists.").option("--identity <name>", "A member identity (repeatable).", collectRepeated).option("--json", "Print the result as JSON.").action((name, options) => {
|
|
68602
68637
|
const members2 = membersOf(options);
|
|
68603
68638
|
requireIdentities(paths, members2);
|
|
68604
|
-
addPool(paths, name, members2);
|
|
68605
|
-
|
|
68639
|
+
const created = addPool(paths, name, members2);
|
|
68640
|
+
reportMutation(options.json, { action: "created", kind: "pool", name, value: created }, () => {
|
|
68641
|
+
console.log(`Created pool "${name}" with ${members2.join(", ")}.`);
|
|
68642
|
+
});
|
|
68606
68643
|
}),
|
|
68607
68644
|
["agent-shim pool add subs --identity work --identity personal"]
|
|
68608
68645
|
);
|
|
68609
68646
|
withExamples(
|
|
68610
|
-
pool.command("set <name>").description("Replace a pool's members.").option("--identity <name>", "A member identity (repeatable); the full new list.", collectRepeated).action((name, options) => {
|
|
68647
|
+
pool.command("set <name>").description("Replace a pool's members.").option("--identity <name>", "A member identity (repeatable); the full new list.", collectRepeated).option("--json", "Print the result as JSON.").action((name, options) => {
|
|
68611
68648
|
const members2 = membersOf(options);
|
|
68612
68649
|
requireIdentities(paths, members2);
|
|
68613
|
-
setPool(paths, name, members2);
|
|
68614
|
-
|
|
68650
|
+
const updated = setPool(paths, name, members2);
|
|
68651
|
+
reportMutation(options.json, { action: "updated", kind: "pool", name, value: updated }, () => {
|
|
68652
|
+
console.log(`Pool "${name}" now has ${members2.join(", ")}.`);
|
|
68653
|
+
});
|
|
68615
68654
|
}),
|
|
68616
68655
|
["agent-shim pool set subs --identity work --identity personal --identity spare"]
|
|
68617
68656
|
);
|
|
@@ -68647,18 +68686,22 @@ function registerPoolCommand(program2, deps) {
|
|
|
68647
68686
|
["agent-shim pool show subs"]
|
|
68648
68687
|
);
|
|
68649
68688
|
withExamples(
|
|
68650
|
-
pool.command("remove <name>").description("Delete a pool. Its member identities are untouched.").option("--yes", "Skip the confirmation prompt.").action(async (name, options) => {
|
|
68689
|
+
pool.command("remove <name>").description("Delete a pool. Its member identities are untouched.").option("--yes", "Skip the confirmation prompt.").option("--json", "Print the result as JSON.").action(async (name, options) => {
|
|
68651
68690
|
requirePool(paths, name);
|
|
68652
68691
|
await confirmRemoval(deps, options.yes, `pool "${name}"`);
|
|
68653
68692
|
removePool(paths, name);
|
|
68654
|
-
|
|
68693
|
+
reportMutation(options.json, { action: "removed", kind: "pool", name }, () => {
|
|
68694
|
+
console.log(`Removed pool "${name}".`);
|
|
68695
|
+
});
|
|
68655
68696
|
}),
|
|
68656
68697
|
["agent-shim pool remove subs --yes"]
|
|
68657
68698
|
);
|
|
68658
68699
|
withExamples(
|
|
68659
|
-
pool.command("use <name>").description("Make launches with no other selection pick a member of this pool.").action((name) => {
|
|
68700
|
+
pool.command("use <name>").description("Make launches with no other selection pick a member of this pool.").option("--json", "Print the result as JSON.").action((name, options) => {
|
|
68660
68701
|
useIdentity(paths, `${POOL_SELECTOR_PREFIX}${name}`);
|
|
68661
|
-
|
|
68702
|
+
reportMutation(options.json, { action: "selected", kind: "pool", name }, () => {
|
|
68703
|
+
console.log(`Active selection is now pool "${name}".`);
|
|
68704
|
+
});
|
|
68662
68705
|
}),
|
|
68663
68706
|
["agent-shim pool use subs"]
|
|
68664
68707
|
);
|
|
@@ -68719,7 +68762,7 @@ function registerProviderCommand(program2, deps) {
|
|
|
68719
68762
|
new Option("--credential-target <target>", "Where the token goes: bearer sets ANTHROPIC_AUTH_TOKEN (default), apiKey sets ANTHROPIC_API_KEY.").choices(
|
|
68720
68763
|
PROVIDER_CREDENTIAL_TARGETS
|
|
68721
68764
|
)
|
|
68722
|
-
).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).action((name, options) => {
|
|
68765
|
+
).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).option("--json", "Print the result as JSON.").action((name, options) => {
|
|
68723
68766
|
const codex = codexConfigFromOptions(options);
|
|
68724
68767
|
const created = addProvider(paths, name, {
|
|
68725
68768
|
...options.kind === void 0 ? {} : { kind: options.kind },
|
|
@@ -68730,7 +68773,9 @@ function registerProviderCommand(program2, deps) {
|
|
|
68730
68773
|
...options.env === void 0 ? {} : { env: options.env },
|
|
68731
68774
|
...codex === void 0 ? {} : { codex }
|
|
68732
68775
|
});
|
|
68733
|
-
|
|
68776
|
+
reportMutation(options.json, { action: "created", kind: "provider", name, value: created }, () => {
|
|
68777
|
+
console.log(`Created provider "${name}" (${describeProviderEndpoint(created)}, credential ${describeCredential(created.credential)}).`);
|
|
68778
|
+
});
|
|
68734
68779
|
}),
|
|
68735
68780
|
[
|
|
68736
68781
|
"agent-shim provider add z --display-name z.ai --base-url https://api.z.ai/api/anthropic --credential env:Z_API_TOKEN",
|
|
@@ -68752,8 +68797,9 @@ function registerProviderCommand(program2, deps) {
|
|
|
68752
68797
|
).option("--env <KEY=VALUE>", "Add or replace an environment entry for the child (repeatable).", collectStringPair).option("--unset-env <KEY>", "Remove an environment entry (repeatable).", collectRepeated).option("--codex-default-model <model>", "Codex providers: replace the model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: set the codex model one tier maps to (repeatable; other tiers are kept).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: replace the default reasoning effort.").choices(CODEX_EFFORTS));
|
|
68753
68798
|
addCredentialCacheOptions(providerSet);
|
|
68754
68799
|
withExamples(
|
|
68755
|
-
providerSet.action((name,
|
|
68756
|
-
|
|
68800
|
+
providerSet.option("--json", "Print the result as JSON.").action((name, allOptions) => {
|
|
68801
|
+
const { json: json2, ...options } = allOptions;
|
|
68802
|
+
if (Object.entries(allOptions).every(([key, value]) => key === "json" || value === void 0)) {
|
|
68757
68803
|
throw new UsageError(
|
|
68758
68804
|
"Nothing to change: pass --display-name, --base-url, --credential, --credential-target, a --credential-cache option, --env, --unset-env, --codex-default-model, --codex-model or --codex-effort."
|
|
68759
68805
|
);
|
|
@@ -68770,7 +68816,9 @@ function registerProviderCommand(program2, deps) {
|
|
|
68770
68816
|
...options.env === void 0 ? {} : { env: options.env },
|
|
68771
68817
|
...options.unsetEnv === void 0 ? {} : { unsetEnv: options.unsetEnv }
|
|
68772
68818
|
});
|
|
68773
|
-
|
|
68819
|
+
reportMutation(json2, { action: "updated", kind: "provider", name, value: updated }, () => {
|
|
68820
|
+
console.log(`Updated provider "${name}" (${describeProviderEndpoint(updated)}, credential ${describeCredential(updated.credential)}).`);
|
|
68821
|
+
});
|
|
68774
68822
|
}),
|
|
68775
68823
|
[
|
|
68776
68824
|
"agent-shim provider set z --base-url https://api.z.ai/api/anthropic",
|
|
@@ -68824,13 +68872,15 @@ function registerProviderCommand(program2, deps) {
|
|
|
68824
68872
|
["agent-shim provider show z", "agent-shim provider show z --json"]
|
|
68825
68873
|
);
|
|
68826
68874
|
withExamples(
|
|
68827
|
-
provider.command("remove <name>").description("Delete a provider definition.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (name, options) => {
|
|
68875
|
+
provider.command("remove <name>").description("Delete a provider definition.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").option("--json", "Print the result as JSON.").action(async (name, options) => {
|
|
68828
68876
|
if (!providerExists(paths, name)) {
|
|
68829
68877
|
throw new ProviderNotFoundError(name);
|
|
68830
68878
|
}
|
|
68831
68879
|
await confirmRemoval(deps, options.yes, `provider "${name}"`);
|
|
68832
68880
|
removeProvider(paths, name);
|
|
68833
|
-
|
|
68881
|
+
reportMutation(options.json, { action: "removed", kind: "provider", name }, () => {
|
|
68882
|
+
console.log(`Removed provider "${name}".`);
|
|
68883
|
+
});
|
|
68834
68884
|
}),
|
|
68835
68885
|
["agent-shim provider remove z --yes"]
|
|
68836
68886
|
);
|
|
@@ -68856,21 +68906,27 @@ function registerRuleCommand(program2, deps) {
|
|
|
68856
68906
|
["agent-shim rule add ~/work/acme --config-profile client-acme", "agent-shim rule list"]
|
|
68857
68907
|
);
|
|
68858
68908
|
withExamples(
|
|
68859
|
-
rule.command("add <path>").description("Add a directory rule for a path. Fails if a rule for that exact path already exists.").option("--config-profile <profile>", "Configuration profile to select under this path.").option("--identity <identity>", "Identity to pin under this path.").action(async (rulePath,
|
|
68909
|
+
rule.command("add <path>").description("Add a directory rule for a path. Fails if a rule for that exact path already exists.").option("--config-profile <profile>", "Configuration profile to select under this path.").option("--identity <identity>", "Identity to pin under this path.").option("--json", "Print the result as JSON.").action(async (rulePath, allOptions) => {
|
|
68910
|
+
const { json: json2, ...options } = allOptions;
|
|
68860
68911
|
await checkRuleTargets(deps, options);
|
|
68861
|
-
addDirectoryRule(paths, rulePath, options);
|
|
68862
|
-
|
|
68912
|
+
const created = addDirectoryRule(paths, rulePath, options);
|
|
68913
|
+
reportMutation(json2, { action: "created", kind: "rule", name: rulePath, value: created }, () => {
|
|
68914
|
+
console.log(`Added directory rule for "${rulePath}".`);
|
|
68915
|
+
});
|
|
68863
68916
|
}),
|
|
68864
68917
|
["agent-shim rule add ~/work/acme --config-profile client-acme", "agent-shim rule add ~/personal --identity personal"]
|
|
68865
68918
|
);
|
|
68866
68919
|
withExamples(
|
|
68867
|
-
rule.command("set <path>").description("Update the directory rule for a path.").option("--config-profile <profile>", "Configuration profile to select under this path.").option("--no-config-profile", "Stop selecting a configuration profile under this path.").option("--identity <identity>", "Identity to pin under this path.").option("--no-identity", "Stop pinning an identity under this path.").action(async (rulePath,
|
|
68920
|
+
rule.command("set <path>").description("Update the directory rule for a path.").option("--config-profile <profile>", "Configuration profile to select under this path.").option("--no-config-profile", "Stop selecting a configuration profile under this path.").option("--identity <identity>", "Identity to pin under this path.").option("--no-identity", "Stop pinning an identity under this path.").option("--json", "Print the result as JSON.").action(async (rulePath, allOptions) => {
|
|
68921
|
+
const { json: json2, ...options } = allOptions;
|
|
68868
68922
|
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
68869
68923
|
throw new UsageError("Nothing to change: pass --config-profile, --no-config-profile, --identity or --no-identity.");
|
|
68870
68924
|
}
|
|
68871
68925
|
await checkRuleTargets(deps, options);
|
|
68872
|
-
updateDirectoryRule(paths, rulePath, options);
|
|
68873
|
-
|
|
68926
|
+
const updated = updateDirectoryRule(paths, rulePath, options);
|
|
68927
|
+
reportMutation(json2, { action: "updated", kind: "rule", name: rulePath, value: updated }, () => {
|
|
68928
|
+
console.log(`Updated directory rule for "${rulePath}".`);
|
|
68929
|
+
});
|
|
68874
68930
|
}),
|
|
68875
68931
|
["agent-shim rule set ~/work/acme --identity work", "agent-shim rule set ~/work/acme --no-config-profile"]
|
|
68876
68932
|
);
|
|
@@ -68907,13 +68963,15 @@ function registerRuleCommand(program2, deps) {
|
|
|
68907
68963
|
["agent-shim rule show ~/work/acme"]
|
|
68908
68964
|
);
|
|
68909
68965
|
withExamples(
|
|
68910
|
-
rule.command("remove <path>").description("Remove the directory rule for a path.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (rulePath, options) => {
|
|
68966
|
+
rule.command("remove <path>").description("Remove the directory rule for a path.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").option("--json", "Print the result as JSON.").action(async (rulePath, options) => {
|
|
68911
68967
|
if (!listDirectoryRules(paths).some((entry) => entry.path === rulePath)) {
|
|
68912
68968
|
throw new DirectoryRuleNotFoundError(rulePath);
|
|
68913
68969
|
}
|
|
68914
68970
|
await confirmRemoval(deps, options.yes, `the directory rule for "${rulePath}"`);
|
|
68915
68971
|
removeDirectoryRule(paths, rulePath);
|
|
68916
|
-
|
|
68972
|
+
reportMutation(options.json, { action: "removed", kind: "rule", name: rulePath }, () => {
|
|
68973
|
+
console.log(`Removed directory rule for "${rulePath}".`);
|
|
68974
|
+
});
|
|
68917
68975
|
}),
|
|
68918
68976
|
["agent-shim rule remove ~/work/acme --yes"]
|
|
68919
68977
|
);
|
|
@@ -15,6 +15,17 @@ export interface CommandDeps {
|
|
|
15
15
|
}
|
|
16
16
|
/** Prints `value` as indented JSON on standard output: the one `--json` output format every `list`, `show`, `check`, `doctor` and `headroom status` command shares. */
|
|
17
17
|
export declare function printJson(value: unknown): void;
|
|
18
|
+
/** What a mutating command did, as the one object `--json` prints in place of its text output. */
|
|
19
|
+
export interface MutationReport {
|
|
20
|
+
readonly action: "created" | "updated" | "removed" | "selected";
|
|
21
|
+
/** The noun the command works on: `identity`, `profile`, `provider`, `pool` or `rule`. */
|
|
22
|
+
readonly kind: string;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
/** The stored object after the change; absent for a removal and for a selection. */
|
|
25
|
+
readonly value?: unknown;
|
|
26
|
+
}
|
|
27
|
+
/** Reports a mutating command's outcome: the `MutationReport` as JSON under `--json`, otherwise whatever `printText` prints. */
|
|
28
|
+
export declare function reportMutation(json: boolean | undefined, report: MutationReport, printText: () => void): void;
|
|
18
29
|
/**
|
|
19
30
|
* Appends an `Examples:` block to `command`'s help output, one `$ agent-shim ...` line per entry. Every command registers at least one, so `--help` on any of them shows a runnable invocation, not just its option list.
|
|
20
31
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.12.1",
|
|
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>",
|