agent-shim 7.6.1 → 7.8.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 -1
- package/dist/cli.cjs +3714 -3687
- package/dist/index.cjs +1087 -183
- package/dist/index.mjs +1017 -168
- package/dist/types/cli/bool.d.ts +8 -0
- package/dist/types/cli/parsers.d.ts +40 -0
- package/dist/types/configProfilesStore.d.ts +61 -0
- package/dist/types/credential.d.ts +136 -0
- package/dist/types/credentialCache.d.ts +46 -0
- package/dist/types/directoryRulesStore.d.ts +43 -0
- package/dist/types/frontdoor/connect.d.ts +7 -6
- package/dist/types/frontdoor/route.d.ts +112 -0
- package/dist/types/frontdoor/tap.d.ts +2 -1
- package/dist/types/headroom/headers.d.ts +11 -0
- package/dist/types/identityStore.d.ts +85 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/launcher/flags.d.ts +96 -0
- package/dist/types/launcher/identity.d.ts +95 -0
- package/dist/types/poolStore.d.ts +18 -0
- package/dist/types/providersStore.d.ts +137 -0
- package/package.json +1 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* - the per-identity usage snapshot a statusline or launcher reads: its schema and the reader over an injected filesystem;
|
|
8
8
|
* - the state root's layout (`resolveAgentShimHome`, `resolveLayoutPaths`, `buildLayoutPaths`), which includes adopting an existing `~/.claude-use` in place, and the Zod schema and inferred type of every configuration file (identity, configuration profile, provider, pool, directory rules, global config, credential), so a tool can validate or generate them with the same definitions the CLI uses.
|
|
9
9
|
*
|
|
10
|
+
* Creating and changing identities, configuration profiles, providers, pools and directory rules: the `*Store` modules, which take the state root's `LayoutPaths`, return typed values and throw `CliError` subclasses.
|
|
11
|
+
*
|
|
10
12
|
* Everything the CLI alone needs (commander wiring, prompts, `doctor`, `check`) is deliberately not exported here.
|
|
11
13
|
*/
|
|
12
14
|
export { resolveDecisions, topLevelNames, type ResolveDecisionsInput, type ResolvedState } from "./resolve/pipeline";
|
|
@@ -24,3 +26,8 @@ export { AMBIENT_CREDENTIAL_VARS, detectAmbientCredential, evaluateAmbientCreden
|
|
|
24
26
|
export { buildLayoutPaths, resolveAgentShimHome, resolveClaudeHome, resolveLayoutPaths, type LayoutPaths } from "./paths";
|
|
25
27
|
export { CliError, EXIT_FAILURE, EXIT_USAGE, UsageError } from "./cliError";
|
|
26
28
|
export { CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DirectoryRuleSchema, DirectoryRulesSchema, EntryValueSchema, GlobalConfigSchema, IdentitySchema, PoolNameSchema, PoolSchema, PortableConfigSchema, ProviderSchema, WhenSchema, type CategoryMap, type ConfigProfile, type Credential, type CredentialSource, type DirectoryRule, type DirectoryRules, type EntryValue, type GlobalConfig, type Identity, type Pool, type PortableConfig, type Provider, type WhenCondition, } from "./config/schema";
|
|
29
|
+
export { addIdentity, IdentityAlreadyExistsError, IdentityNotFoundError, identityExists, InvalidIdentityNameError, isIdentityDirectoryName, listIdentities, readActiveIdentity, readIdentity, removeIdentity, setAllowAmbientCredential, setDefaultConfigProfile, setIdentityCredential, useIdentity, type IdentityCredentialChange, type IdentityListEntry, type IdentityListing, type UnreadableIdentityListEntry, } from "./identityStore";
|
|
30
|
+
export { createProfile, InvalidCategoryNameError, listProfiles, ProfileAlreadyExistsError, ProfileNotFoundError, profileExists, readGlobalConfig, readProfile, removeProfile, setGlobalDefaultProfile, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, type ProfileListEntry, } from "./configProfilesStore";
|
|
31
|
+
export { addProvider, describeProviderEndpoint, InvalidProviderNameError, LegacyProviderFileError, listProviders, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, providerExists, readProvider, removeProvider, updateProvider, type AddProviderInput, type ProviderListEntry, type UpdateProviderInput, } from "./providersStore";
|
|
32
|
+
export { addPool, PoolNotFoundError, readPools, removePool, requirePool, setPool } from "./poolStore";
|
|
33
|
+
export { addDirectoryRule, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, listDirectoryRules, readDirectoryRules, removeDirectoryRule, updateDirectoryRule, writeDirectoryRules, type AddDirectoryRuleOptions, type UpdateDirectoryRuleOptions, } from "./directoryRulesStore";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { LaunchFlags, Provider } from "../config/schema";
|
|
2
|
+
import { type ResolvedCredential } from "../credential";
|
|
3
|
+
import type { FrontDoorUp, HeadroomUp } from "./ports";
|
|
4
|
+
/** The fully resolved launch flags for one launch. */
|
|
5
|
+
export interface ResolvedLaunchFlags {
|
|
6
|
+
readonly skipPermissions: boolean;
|
|
7
|
+
readonly remoteControl: boolean;
|
|
8
|
+
readonly headroom: boolean;
|
|
9
|
+
/** Whether the launch routes through the front door so its requests are recorded, even with no provider and no headroom. */
|
|
10
|
+
readonly trackUsage: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** The one-off command-line forms of the four boolean launch flags, each undefined when neither its positive nor its `--no-` form was given. */
|
|
13
|
+
interface LaunchFlagOverrides {
|
|
14
|
+
readonly skipPermissions?: boolean;
|
|
15
|
+
readonly remoteControl?: boolean;
|
|
16
|
+
readonly headroom?: boolean;
|
|
17
|
+
readonly trackUsage?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Inputs to `resolveLaunchFlags`. */
|
|
20
|
+
export interface ResolveLaunchFlagsParams {
|
|
21
|
+
/** The cascade's resolved `launch` block, when a cascade was loaded for this launch. */
|
|
22
|
+
readonly cascade?: LaunchFlags;
|
|
23
|
+
/** The launch's own `--[no-]skip-permissions`, `--[no-]remote-control`, `--[no-]headroom` and `--[no-]track-usage` flags. */
|
|
24
|
+
readonly flags?: LaunchFlagOverrides;
|
|
25
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
26
|
+
/** What `trackUsage` is when no flag, environment variable or cascade setting says: off, except for a pool launch, whose pick reads the usage the front door records. */
|
|
27
|
+
readonly trackUsageDefault?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolves `skipPermissions`/`remoteControl`/`headroom`/`trackUsage` for one launch. Each setting has the same three forms, decided in the same order: an explicit command-line flag outright, then its environment variable (`AGENT_SHIM_SKIP_PERMISSIONS`, `AGENT_SHIM_REMOTE_CONTROL`, `AGENT_SHIM_HEADROOM`, `AGENT_SHIM_TRACK_USAGE`), then the cascade, and OFF when none of them says otherwise (`trackUsageDefault` changes that one fallback). The flag outranks the environment variable because it is the more deliberate of the two one-off forms (typed on this very command line, not inherited from a shell profile), and both outrank the cascade because they are one-off overrides of it.
|
|
31
|
+
*
|
|
32
|
+
* Environment variables read with the shared boolean vocabulary (`true`/`1`, `false`/`0`), so `AGENT_SHIM_SKIP_PERMISSIONS=0` switches off a cascade's `skipPermissions: true` for one launch; any other value throws `InvalidEnvBoolError`.
|
|
33
|
+
*
|
|
34
|
+
* This default-off posture is a deliberate change from the legacy bash tool, which passed `--dangerously-skip-permissions` unconditionally on every launch.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveLaunchFlags(params: ResolveLaunchFlagsParams): ResolvedLaunchFlags;
|
|
37
|
+
/**
|
|
38
|
+
* Builds the tool's own flag arguments from resolved launch flags.
|
|
39
|
+
*
|
|
40
|
+
* `--remote-control=` always carries a literal trailing `=` with an empty value — never bare `--remote-control` — confirmed as a deliberate fix in the legacy script's own git history to stop the flag from consuming the next positional argument as its value.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildFlagArgs(flags: ResolvedLaunchFlags): string[];
|
|
43
|
+
/** Inputs to `buildArgv`. */
|
|
44
|
+
export interface BuildArgvParams {
|
|
45
|
+
readonly toolFlags: readonly string[];
|
|
46
|
+
readonly extraFlags: readonly string[];
|
|
47
|
+
readonly passthrough: readonly string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Assembles the final argv passed to the real `claude` binary: tool flags, then `$CLAUDE_EXTRA_FLAGS`, then the user's own forwarded arguments, in that exact order.
|
|
51
|
+
*
|
|
52
|
+
* Extra flags must land BEFORE the passthrough args — confirmed load-bearing against real wrapper scripts (`cpl`, `mp`, `zpl`) that set `CLAUDE_EXTRA_FLAGS="--print"` and then pass a positional prompt afterwards; reversing this order would feed the prompt to `--print` as if it were a flag value instead of a trailing positional.
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildArgv(params: BuildArgvParams): string[];
|
|
55
|
+
/** The provider resolved for this launch, with its credential already resolved from the provider's credential block. */
|
|
56
|
+
export interface ResolvedProvider {
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly definition: Provider;
|
|
59
|
+
readonly credential: ResolvedCredential;
|
|
60
|
+
}
|
|
61
|
+
/** A resolved provider with the base URL its sessions are sent to: the front door's provider-scoped address, which exists only once the door is up and is the same shape for both kinds (the door is what decides where the request goes from there). */
|
|
62
|
+
export interface RoutedProvider extends ResolvedProvider {
|
|
63
|
+
readonly baseUrl: string;
|
|
64
|
+
}
|
|
65
|
+
/** Inputs to `buildEnv`. */
|
|
66
|
+
export interface BuildEnvParams {
|
|
67
|
+
readonly baseEnv: Readonly<Record<string, string | undefined>>;
|
|
68
|
+
/** True when `CLAUDE_CONFIG_DIR` was already set and the escape hatch applied — `buildEnv` must leave it untouched in that case. */
|
|
69
|
+
readonly configDirEscapeHatch: boolean;
|
|
70
|
+
/** The identity name resolved for this launch, when one was resolved. */
|
|
71
|
+
readonly resolvedIdentityName?: string;
|
|
72
|
+
readonly identitiesDir: string;
|
|
73
|
+
/** The provider resolved for this launch, when one was resolved, with the base URL it routes to. Its credential is resolved by the caller because refusing an unusable one needs the caller's log/exit ports. */
|
|
74
|
+
readonly provider?: RoutedProvider;
|
|
75
|
+
/** The launching identity's own resolved credential, when it has a credential block and no provider was selected. A provider's credential authenticates against the provider's endpoint, so the identity's is never applied alongside one. */
|
|
76
|
+
readonly identityCredential?: ResolvedCredential;
|
|
77
|
+
/** The front door this launch routes through, when one is engaged (a provider is selected, or headroom resolved on). It is what the child talks to: its provider listener for a provider session, its CONNECT surface for an OAuth one. */
|
|
78
|
+
readonly frontdoor?: FrontDoorUp;
|
|
79
|
+
/** The headroom daemon this launch's requests must pass through (as the door's headroom hop), when headroom resolved on. The child never talks to it directly. */
|
|
80
|
+
readonly headroom?: HeadroomUp;
|
|
81
|
+
/** The per-launch session id, stamped into the session header the door identifies this launch's requests by. */
|
|
82
|
+
readonly sessionId: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Builds the environment the real `claude` binary is spawned with.
|
|
86
|
+
*
|
|
87
|
+
* When the `CLAUDE_CONFIG_DIR`-already-set escape hatch applied, or no identity was resolved at all (a bare launch with no active identity, matching the legacy script's own "no profile means plain `~/.claude`" behaviour), `CLAUDE_CONFIG_DIR` is left untouched. Otherwise `CLAUDE_CONFIG_DIR` is set to the resolved identity's own directory under `identitiesDir` — farm population into that directory is Phase 5's job, not this function's.
|
|
88
|
+
*
|
|
89
|
+
* A resolved provider is applied regardless of the identity outcome, because it selects which API endpoint the child talks to, not which login's data it sees: `ANTHROPIC_BASE_URL` points at the provider's routed base URL (always the front door's provider-scoped address), `AGENT_SHIM_PROVIDER` names the provider for the statusline, the provider's own `env` entries land verbatim, and its resolved credential is exported as its target's variable (`credentialVariables`), with the other credential variables removed so an ambient one inherited from the parent cannot outrank it. Without a provider, an identity's own resolved credential is exported the same way. The token only ever reaches this environment, never the child's argv or a log line.
|
|
90
|
+
*
|
|
91
|
+
* A resolved front door is the whole of the child's routing, on top of the provider: `ANTHROPIC_CUSTOM_HEADERS` gains the launcher-injected session headers (identity, session id, the launch's capability token, and, when headroom resolved on, the headroom flag and the project identity headroom scopes memory to), merged with any headers the provider's own `env` or the parent environment already set. The door strips every one of them before anything leaves the machine; the token is what authorises the session's requests at the door in the first place. `NODE_EXTRA_CA_CERTS` points at the door's trust bundle in both modes, because the child reaches the door over TLS signed by agent-shim's CA either way. With a provider, the child's HTTPS base URL already names the door's provider listener, so a process that merely binds that port cannot present a certificate the child accepts. Without one (an OAuth launch), the base URL is left exactly as the parent environment had it, because Claude Code enables Remote Control and connectors only against the real `api.anthropic.com`; routing happens one layer down instead, with `HTTPS_PROXY` pointing the child at the door's CONNECT surface and carrying the launch's capability as its proxy credential (the surface refuses any CONNECT without a live one), so the child still believes it is talking to the real `api.anthropic.com` while the surface's terminated TLS feeds the routed paths to the same pipeline. `HEADROOM_PROXY_URL` names the headroom daemon for anything else that wants it; the child never talks to that daemon directly, the door's hop does.
|
|
92
|
+
*
|
|
93
|
+
* `$CLAUDE_EXTRA_FLAGS` is never stripped from the child's environment: some wrappers set it two process-levels up and rely on inheritance through a `claude` invoked from inside a running session.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildEnv(params: BuildEnvParams): Record<string, string | undefined>;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type LoadedFile } from "../config/load";
|
|
2
|
+
import { type Identity } from "../config/schema";
|
|
3
|
+
import type { FsPort } from "./ports";
|
|
4
|
+
/** Which precedence rule produced an identity decision. */
|
|
5
|
+
export type IdentityDecisionSource =
|
|
6
|
+
/** `CLAUDE_CONFIG_DIR` was already set: identity resolution is skipped entirely and the real binary uses whatever it already points to. */
|
|
7
|
+
"config-dir-escape-hatch"
|
|
8
|
+
/** A leading `@name` argv[0] positional, or its explicit form `--identity <name>`. */
|
|
9
|
+
| "argv"
|
|
10
|
+
/** The `AGENT_SHIM_IDENTITY` environment variable. */
|
|
11
|
+
| "env"
|
|
12
|
+
/** A directory rule pinning an identity to the current path. */
|
|
13
|
+
| "directory-pin"
|
|
14
|
+
/** The persisted `~/.agent-shim/active-identity` file. */
|
|
15
|
+
| "active-identity-file"
|
|
16
|
+
/** Nothing resolved an identity at all — a bare launch with no active identity. */
|
|
17
|
+
| "none";
|
|
18
|
+
/** The pool a `pool:<name>` selector names, or undefined when `selector` names an identity directly. */
|
|
19
|
+
export declare function poolNameOf(selector: string): string | undefined;
|
|
20
|
+
/** The result of deciding which identity applies to this launch. */
|
|
21
|
+
export interface IdentityDecision {
|
|
22
|
+
/** The resolved identity name. Absent when the escape hatch applied, when nothing resolved one, or when a pool was selected (the launcher picks a member from `pool`). */
|
|
23
|
+
readonly name?: string;
|
|
24
|
+
/** The pool selected by a `pool:<name>` selector, when the launch named a pool instead of an identity. */
|
|
25
|
+
readonly pool?: string;
|
|
26
|
+
readonly source: IdentityDecisionSource;
|
|
27
|
+
/** True when `CLAUDE_CONFIG_DIR` was already set and every step below was skipped as a result. */
|
|
28
|
+
readonly configDirEscapeHatch: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Inputs to `decideIdentity`, in the exact precedence order the README's CLI reference table documents. */
|
|
31
|
+
export interface DecideIdentityParams {
|
|
32
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
33
|
+
/** The identity `parseLauncherArgv` found in a leading `@name` or an `--identity <name>` flag, if either was given. */
|
|
34
|
+
readonly argv0Identity?: string;
|
|
35
|
+
/** An identity pinned to `$PWD` by a directory rule. Accepted as an already-resolved value here — the rules-loading code that produces it lands in Phase 4/5. */
|
|
36
|
+
readonly directoryPinnedIdentity?: string;
|
|
37
|
+
/** Reads the persisted active-identity file, returning undefined when it does not exist or is empty. Injected so this stays pure. */
|
|
38
|
+
readonly readActiveIdentityFile: () => string | undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Decides which identity applies to this launch, in precedence order:
|
|
42
|
+
*
|
|
43
|
+
* 1. If `CLAUDE_CONFIG_DIR` is already set, skip identity/cascade resolution entirely: a deliberate carry-forward of the legacy script's own "don't override an explicit launcher" escape hatch.
|
|
44
|
+
* 2. A leading `@name` argv[0] positional, or `--identity <name>`.
|
|
45
|
+
* 3. The `AGENT_SHIM_IDENTITY` environment variable.
|
|
46
|
+
* 4. A directory-pinned identity from a directory rule.
|
|
47
|
+
* 5. The persisted `~/.agent-shim/active-identity` file.
|
|
48
|
+
*
|
|
49
|
+
* Each of steps 2 to 5 may name `pool:<name>` instead of an identity; the decision then carries `pool` and no `name`, and the launcher picks the member.
|
|
50
|
+
*
|
|
51
|
+
* An empty string counts as unset for `CLAUDE_CONFIG_DIR` and `AGENT_SHIM_IDENTITY`, consistent with how this project treats empty-string environment variables everywhere else (see `src/paths.ts` and the ambient-credential guard).
|
|
52
|
+
*/
|
|
53
|
+
export declare function decideIdentity(params: DecideIdentityParams): IdentityDecision;
|
|
54
|
+
/** Which precedence rule produced a configuration-profile decision. */
|
|
55
|
+
export type ConfigProfileDecisionSource =
|
|
56
|
+
/** An explicit `--config-profile` CLI flag. */
|
|
57
|
+
"cli-flag"
|
|
58
|
+
/** The `AGENT_SHIM_CONFIG_PROFILE` environment variable. */
|
|
59
|
+
| "env"
|
|
60
|
+
/** A directory rule's `configProfile` selection for `$PWD`. */
|
|
61
|
+
| "directory-rule"
|
|
62
|
+
/** The active identity's own declared `defaultConfigProfile`. */
|
|
63
|
+
| "identity-default"
|
|
64
|
+
/** The user-global `~/.agent-shim/config.json` default. */
|
|
65
|
+
| "global-default"
|
|
66
|
+
/** Nothing resolved a configuration profile at all. */
|
|
67
|
+
| "none";
|
|
68
|
+
/** The result of deciding which configuration profile applies to this launch. */
|
|
69
|
+
export interface ConfigProfileDecision {
|
|
70
|
+
readonly name?: string;
|
|
71
|
+
readonly source: ConfigProfileDecisionSource;
|
|
72
|
+
}
|
|
73
|
+
/** Inputs to `decideConfigProfile`, in the exact precedence order the README's "Configuration profiles" section documents. */
|
|
74
|
+
export interface DecideConfigProfileParams {
|
|
75
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
76
|
+
readonly cliFlagConfigProfile?: string;
|
|
77
|
+
readonly directoryRuleConfigProfile?: string;
|
|
78
|
+
readonly identityDefaultConfigProfile?: string;
|
|
79
|
+
readonly globalDefaultConfigProfile?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Decides which configuration profile applies to this launch, in precedence order:
|
|
83
|
+
*
|
|
84
|
+
* 1. An explicit `--config-profile` flag or `AGENT_SHIM_CONFIG_PROFILE` environment variable (this run only).
|
|
85
|
+
* 2. A directory rule's `configProfile` selection for `$PWD`.
|
|
86
|
+
* 3. The active identity's own declared default (`defaultConfigProfile` in its `identity.json`).
|
|
87
|
+
* 4. A global default (`~/.agent-shim/config.json`).
|
|
88
|
+
*/
|
|
89
|
+
export declare function decideConfigProfile(params: DecideConfigProfileParams): ConfigProfileDecision;
|
|
90
|
+
/**
|
|
91
|
+
* Reads and validates one identity's `identity.json` from `<identitiesDir>/<name>/identity.json`, via `IdentitySchema`.
|
|
92
|
+
*
|
|
93
|
+
* Returns undefined when the file does not exist (e.g. the identity was resolved by name but never actually created — `agent-shim identity add` is Phase 4's job, not this one's). Throws `ConfigValidationError` when the file exists but fails validation, the same as any other config file in this project.
|
|
94
|
+
*/
|
|
95
|
+
export declare function loadIdentity(identitiesDir: string, name: string, fs: FsPort): LoadedFile<Identity> | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CliError } from "./cliError";
|
|
2
|
+
import { type Pool } from "./config/schema";
|
|
3
|
+
import type { LayoutPaths } from "./paths";
|
|
4
|
+
/** Raised when a command names a pool that is not defined in the global config. */
|
|
5
|
+
export declare class PoolNotFoundError extends CliError {
|
|
6
|
+
readonly poolName: string;
|
|
7
|
+
constructor(poolName: string);
|
|
8
|
+
}
|
|
9
|
+
/** The pools defined in `~/.agent-shim/config.json`, by name. */
|
|
10
|
+
export declare function readPools(paths: LayoutPaths): Readonly<Record<string, Pool>>;
|
|
11
|
+
/** The pool named `name`; throws `PoolNotFoundError` when none is defined. */
|
|
12
|
+
export declare function requirePool(paths: LayoutPaths, name: string): Pool;
|
|
13
|
+
/** Defines a new pool. Throws `InvalidPoolNameError` for a name `PoolNameSchema` rejects and `PoolAlreadyExistsError` for one already defined. */
|
|
14
|
+
export declare function addPool(paths: LayoutPaths, name: string, identities: readonly string[]): Pool;
|
|
15
|
+
/** Replaces an existing pool's members. Throws `PoolNotFoundError` when it is not defined. */
|
|
16
|
+
export declare function setPool(paths: LayoutPaths, name: string, identities: readonly string[]): Pool;
|
|
17
|
+
/** Removes a pool. Throws `PoolNotFoundError` when it is not defined. Anything that selected it (an active-identity file, a directory rule) is left for `doctor` to report, as with a removed identity. */
|
|
18
|
+
export declare function removePool(paths: LayoutPaths, name: string): void;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { type PROVIDER_CREDENTIAL_TARGETS, type PROVIDER_KINDS, type CodexProviderConfig, type CredentialCache, type CredentialSource, type Provider } from "./config/schema";
|
|
2
|
+
import { CliError, UsageError } from "./cliError";
|
|
3
|
+
import { type CredentialPort } from "./credential";
|
|
4
|
+
import type { ResolvedProvider } from "./launcher/flags";
|
|
5
|
+
import type { FsPort } from "./launcher/ports";
|
|
6
|
+
import { type CascadeInput } from "./resolve/walk";
|
|
7
|
+
import type { LayoutPaths } from "./paths";
|
|
8
|
+
/** Raised by any operation that requires a provider to already exist, when it does not. */
|
|
9
|
+
export declare class ProviderNotFoundError extends CliError {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
constructor(name: string);
|
|
12
|
+
}
|
|
13
|
+
/** Raised by `addProvider` when a provider with the given name already has a file. */
|
|
14
|
+
export declare class ProviderAlreadyExistsError extends CliError {
|
|
15
|
+
readonly providerName: string;
|
|
16
|
+
constructor(providerName: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Raised by `addProvider` when `name` fails the provider naming rule: the same rule `IdentitySchema` applies to identity names (start with a letter or number, then letters, numbers, dots, hyphens, underscores, and at signs). Keeping the two rules identical means a name that works for one works for the other, and neither vocabulary can ever produce a path segment that escapes `providers/` or `identities/`.
|
|
20
|
+
*/
|
|
21
|
+
export declare class InvalidProviderNameError extends CliError {
|
|
22
|
+
readonly attemptedName: string;
|
|
23
|
+
constructor(attemptedName: string);
|
|
24
|
+
}
|
|
25
|
+
/** True when a provider file exists for `name`, regardless of whether it validates. */
|
|
26
|
+
export declare function providerExists(paths: LayoutPaths, name: string): boolean;
|
|
27
|
+
/** Written in a replacement in place of an old fixed `env.ANTHROPIC_AUTH_TOKEN` value, which is never printed: the person converting the file copies the value across themselves. */
|
|
28
|
+
export declare const LEGACY_LITERAL_PLACEHOLDER = "<the value of env.ANTHROPIC_AUTH_TOKEN>";
|
|
29
|
+
/** What converting one old-format provider file involves: the old fields it uses, and the whole file rewritten in the current format. */
|
|
30
|
+
export interface LegacyProviderConversion {
|
|
31
|
+
readonly fields: readonly string[];
|
|
32
|
+
readonly replacement: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Recognises a provider file written in the format before the credential block (a `tokenEnv`, `tokenCommand` or `authScheme` field, or a credential variable in `env`, and no `credential`) and builds its exact replacement: `tokenEnv` becomes an `env` source, `tokenCommand` a `command` source, a non-empty fixed `env.ANTHROPIC_AUTH_TOKEN` a `literal` source (its value replaced by `LEGACY_LITERAL_PLACEHOLDER`, never printed), `authScheme` the `target`, and the credential variables leave `env`. Undefined for anything else, including a file that is merely invalid.
|
|
36
|
+
*/
|
|
37
|
+
export declare function legacyProviderConversion(raw: unknown): LegacyProviderConversion | undefined;
|
|
38
|
+
/** Raised when a provider file is still in the format before the credential block, naming the old fields and giving the exact replacement. */
|
|
39
|
+
export declare class LegacyProviderFileError extends CliError {
|
|
40
|
+
readonly filePath: string;
|
|
41
|
+
readonly conversion: LegacyProviderConversion;
|
|
42
|
+
constructor(filePath: string, conversion: LegacyProviderConversion);
|
|
43
|
+
}
|
|
44
|
+
/** Reads and validates one provider definition, or undefined when it does not exist. */
|
|
45
|
+
export declare function readProvider(paths: LayoutPaths, name: string): Provider | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Reads and validates one provider definition through an injected `FsPort`, the same way `loadIdentity` reads an `identity.json`: the launcher never touches the real filesystem directly, so provider loading must flow through the port it is already handed.
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadProvider(providersDir: string, name: string, port: FsPort): Provider | undefined;
|
|
50
|
+
/** One provider definition as reported by `listProviders`. */
|
|
51
|
+
export interface ProviderListEntry {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly provider: Provider;
|
|
54
|
+
}
|
|
55
|
+
/** Lists every provider under `providersDir` that has a valid `<name>.json`. A file that fails validation is skipped here; `provider list` is the place a broken definition gets surfaced, not a launch. */
|
|
56
|
+
export declare function listProviders(paths: LayoutPaths): readonly ProviderListEntry[];
|
|
57
|
+
/** The credential targets a provider may use. */
|
|
58
|
+
export type ProviderCredentialTarget = (typeof PROVIDER_CREDENTIAL_TARGETS)[number];
|
|
59
|
+
/** The kinds of provider. */
|
|
60
|
+
export type ProviderKind = (typeof PROVIDER_KINDS)[number];
|
|
61
|
+
/** Where a provider sends its sessions, for display: an `http` provider's base URL, or the front door for a codex provider (whose address exists only at launch). */
|
|
62
|
+
export declare function describeProviderEndpoint(provider: Provider): string;
|
|
63
|
+
/** Everything `addProvider` writes into a fresh provider file. `baseUrl` is required for an `http` provider and refused for a codex one; `codex` applies only to a codex provider. */
|
|
64
|
+
export interface AddProviderInput {
|
|
65
|
+
readonly kind?: ProviderKind;
|
|
66
|
+
readonly displayName: string;
|
|
67
|
+
readonly baseUrl?: string;
|
|
68
|
+
readonly sources: readonly CredentialSource[];
|
|
69
|
+
readonly target?: ProviderCredentialTarget;
|
|
70
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
71
|
+
readonly codex?: CodexProviderConfig;
|
|
72
|
+
}
|
|
73
|
+
/** Raised when a provider option does not fit the provider's kind: a base URL for a codex provider, a missing one for an http provider, or codex settings for an http provider. */
|
|
74
|
+
export declare class ProviderKindMismatchError extends UsageError {
|
|
75
|
+
constructor(message: string);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Creates a new provider definition. Throws `ProviderAlreadyExistsError` when a provider with this name already has a file, `InvalidProviderNameError` when `name` fails the naming rule, and `ConfigValidationError` when the assembled definition fails `ProviderSchema` (e.g. a `baseUrl` that is not a URL) rather than letting the underlying `ZodError` escape as an unhandled crash.
|
|
79
|
+
*/
|
|
80
|
+
export declare function addProvider(paths: LayoutPaths, name: string, input: AddProviderInput): Provider;
|
|
81
|
+
/**
|
|
82
|
+
* The fields `updateProvider` changes. `sources` replaces the whole ordered source list (a list is set, not patched, since its order is its meaning); `target` changes where the token goes and keeps the sources. `env` entries merge over the existing ones and `unsetEnv` keys are then deleted.
|
|
83
|
+
*/
|
|
84
|
+
export interface UpdateProviderInput {
|
|
85
|
+
readonly displayName?: string;
|
|
86
|
+
readonly baseUrl?: string;
|
|
87
|
+
readonly sources?: readonly CredentialSource[];
|
|
88
|
+
readonly target?: ProviderCredentialTarget;
|
|
89
|
+
/** A new cache block, or false to remove it; undefined leaves the existing one. */
|
|
90
|
+
readonly cache?: CredentialCache | false;
|
|
91
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
92
|
+
readonly unsetEnv?: readonly string[];
|
|
93
|
+
/** Merged over a codex provider's existing settings: a field given here replaces that field, and `models` entries merge per tier. */
|
|
94
|
+
readonly codex?: CodexProviderConfig;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Updates an existing provider definition in place. Throws `ProviderNotFoundError` when it does not exist, and `ConfigValidationError` when the updated definition fails `ProviderSchema`, leaving the file untouched.
|
|
98
|
+
*/
|
|
99
|
+
export declare function updateProvider(paths: LayoutPaths, name: string, input: UpdateProviderInput): Provider;
|
|
100
|
+
/** Deletes a provider definition. Throws `ProviderNotFoundError` when it does not exist. */
|
|
101
|
+
export declare function removeProvider(paths: LayoutPaths, name: string): void;
|
|
102
|
+
/**
|
|
103
|
+
* The provider name the cascade selects through `launch.provider`, if any layer sets one. Last layer wins, the same rule `flattenLayers` applies to every other launch flag.
|
|
104
|
+
*/
|
|
105
|
+
export declare function cascadeProviderName(cascade: CascadeInput): string | undefined;
|
|
106
|
+
/** Inputs to `resolveProvider`. */
|
|
107
|
+
export interface ResolveProviderParams {
|
|
108
|
+
readonly paths: LayoutPaths;
|
|
109
|
+
readonly port: FsPort;
|
|
110
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
111
|
+
/** Resolves the provider's credential sources. Omitted by a caller that cannot read secret files or run commands; a selected provider is then refused rather than launched without its credential. */
|
|
112
|
+
readonly credentials?: CredentialPort;
|
|
113
|
+
/** The `--provider <name>` flag's value, when one was given. It outranks any cascade layer, matching how the cliOverride layer composes last everywhere else. */
|
|
114
|
+
readonly cliProvider?: string;
|
|
115
|
+
/** The assembled-but-unflattened cascade for this launch, when one was loaded. Its layers are scanned for a `launch.provider` selection so a profile, directory rule, portable file, or the global config can pin a provider exactly the way they pin the other launch flags. */
|
|
116
|
+
readonly cascade?: CascadeInput;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The outcome of resolving this launch's provider: either a fully-resolved provider (definition plus its resolved credential), or a refusal the launcher turns into a stderr line and a non-zero exit.
|
|
120
|
+
*
|
|
121
|
+
* A provider whose credential block yields no token exits `CREDENTIAL_UNAVAILABLE_EXIT` (64), because the invocation cannot authenticate. An unknown provider name exits 1, matching every other "named thing not found" refusal in the launcher.
|
|
122
|
+
*/
|
|
123
|
+
export type ProviderResolution = {
|
|
124
|
+
readonly ok: true;
|
|
125
|
+
readonly provider: ResolvedProvider;
|
|
126
|
+
readonly warnings: readonly string[];
|
|
127
|
+
} | {
|
|
128
|
+
readonly ok: false;
|
|
129
|
+
readonly status: number;
|
|
130
|
+
readonly message: string;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Resolves which API provider this launch routes through, if any: the `--provider` flag first, then the cascade's `launch.provider` selection. Returns undefined when nothing selected a provider at all.
|
|
134
|
+
*
|
|
135
|
+
* Pure over its injected ports, so the launcher's tests exercise refusals without touching a real providers directory, secret store or terminal: this function decides, and the caller owns the log/exit side effects.
|
|
136
|
+
*/
|
|
137
|
+
export declare function resolveProvider(params: ResolveProviderParams): ProviderResolution | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.8.0",
|
|
4
4
|
"description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joseph Mearman <joseph@mearman.co.uk>",
|