agent-shim 7.3.0 → 7.5.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 +1 -0
- package/dist/cli.cjs +29 -23
- package/dist/index.cjs +229 -100
- package/dist/index.mjs +203 -100
- package/dist/types/config/schema.d.ts +1 -1
- package/dist/types/frontdoor/connect.d.ts +17 -9
- package/dist/types/index.d.ts +6 -2
- package/package.json +1 -1
|
@@ -6,10 +6,14 @@ import type { ConnectCapture, PassthroughObserver } from "./capture";
|
|
|
6
6
|
*
|
|
7
7
|
* Nothing is tunnelled or intercepted for a client that has not authenticated: every CONNECT request must present a live launch's capability as its proxy credential (`Proxy-Authorization: Basic`, which clients derive from the credential in the `HTTPS_PROXY` URL the launcher sets), or it is answered 407 before any target is dialled, so the port is no open proxy for other local processes. Pending and authenticated connections are bounded by `ConnectLimits`.
|
|
8
8
|
*
|
|
9
|
-
* Every authenticated CONNECT target is blind-tunnelled byte for byte EXCEPT the intercept
|
|
9
|
+
* Every authenticated CONNECT target is blind-tunnelled byte for byte EXCEPT the intercept hosts (Claude Code's own API and the claude.ai control plane), whose TLS this surface terminates with leaf certificates signed by a locally generated CA. On the API host's terminated session, the paths the front door routes (`/v1/`) are handed to the same ordered pipeline the provider listener serves (the client's Authorization header passes through untouched), and every other path there, and every path on the control plane's session, is piped by this surface to that session's own real upstream over TLS, so Remote Control's streaming, OAuth refreshes, and unknown endpoints bypass the pipeline entirely. When a `capture` is configured, those piped exchanges and every CONNECT target are recorded through it (see `./capture.ts`); the forwarding itself is identical either way.
|
|
10
10
|
*/
|
|
11
|
-
/** The
|
|
11
|
+
/** The API host: Claude Code's own upstream, the one host whose `/v1/` paths the routed pipeline serves. */
|
|
12
12
|
export declare const CONNECT_INTERCEPT_HOST = "api.anthropic.com";
|
|
13
|
+
/**
|
|
14
|
+
* Every CONNECT host whose TLS this surface terminates, each with its own leaf and its own HTTP parser: the API host above, and `platform.claude.com`, the claude.ai control plane where Remote Control's long-lived channel and its handshake live. Terminating the second one is what makes a Remote Control login rejection observable at all: its bytes cross this surface either way, and blind-tunnelling them hides exactly the exchange that failed. Only the API host's `/v1/` paths ever reach the routed pipeline; everything else on either session is piped to that session's own real upstream, so the pipeline's identification and authorisation are never asked to serve another host's traffic.
|
|
15
|
+
*/
|
|
16
|
+
export declare const CONNECT_INTERCEPT_HOSTS: readonly string[];
|
|
13
17
|
/** Paths under this prefix are what the routed pipeline serves; everything else on the terminated session goes to the real upstream. */
|
|
14
18
|
export declare const ROUTED_PATH_PREFIX = "/v1/";
|
|
15
19
|
/** The port HTTPS is served on, both the default when a CONNECT authority names none and the port non-headroom paths are piped to on the real upstream. */
|
|
@@ -52,8 +56,8 @@ export interface ConnectTarget {
|
|
|
52
56
|
}
|
|
53
57
|
/** Parses a CONNECT authority (`host:port`, or a bare `host` meaning 443), or undefined when it names no host or a non-numeric port. */
|
|
54
58
|
export declare function parseConnectTarget(authority: string): ConnectTarget | undefined;
|
|
55
|
-
/** Whether a CONNECT target's host (port already stripped) is
|
|
56
|
-
export declare function isInterceptedHost(host: string,
|
|
59
|
+
/** Whether a CONNECT target's host (port already stripped) is one whose TLS this proxy terminates. */
|
|
60
|
+
export declare function isInterceptedHost(host: string, interceptHosts: readonly string[]): boolean;
|
|
57
61
|
/** Whether a request path on the terminated session is one the routed pipeline serves. The query string stays part of the path: `/v1/messages?beta=true` is still the pipeline's. */
|
|
58
62
|
export declare function servedByPipeline(path: string | undefined): boolean;
|
|
59
63
|
/**
|
|
@@ -142,16 +146,20 @@ export interface ConnectEffects {
|
|
|
142
146
|
}
|
|
143
147
|
/** Everything the connect surface needs to route, resolved before it starts. */
|
|
144
148
|
export interface ConnectServerConfig {
|
|
145
|
-
/** The CONNECT
|
|
146
|
-
readonly
|
|
149
|
+
/** The CONNECT hosts whose TLS get terminated, each with its own leaf, its own HTTP parser and its own upstream. */
|
|
150
|
+
readonly interceptHosts: readonly string[];
|
|
151
|
+
/**
|
|
152
|
+
* The one intercept host whose `/v1/` paths `serveRouted` handles: the API host, whose pipeline identification, authorisation and headroom hop are about Anthropic sessions and no other host's traffic.
|
|
153
|
+
*/
|
|
154
|
+
readonly routedHost: string;
|
|
147
155
|
/**
|
|
148
156
|
* Serves one routed path (`/v1/...`) from the terminated session: the same ordered pipeline the provider listener hands requests to, so an OAuth session and a provider session run identical identification, middleware and routing.
|
|
149
157
|
*/
|
|
150
158
|
readonly serveRouted: ConnectRequestHandler;
|
|
151
|
-
/** The leaf to terminate
|
|
159
|
+
/** The leaf to terminate each intercept host with, minted and cached per host. */
|
|
152
160
|
readonly leafFor: (host: string) => LeafCert;
|
|
153
|
-
/** Where non-routed paths on
|
|
154
|
-
readonly
|
|
161
|
+
/** Where non-routed paths on one host's terminated session are piped: that host's own real upstream over TLS. */
|
|
162
|
+
readonly upstreamFor: (host: string) => ConnectForwardTarget;
|
|
155
163
|
/** Whether a capability presented as a CONNECT request's proxy credential belongs to a live launch: the same constant-time check against the same registry the routed pipeline's admission makes, read fresh on every call because launches come and go. */
|
|
156
164
|
readonly isLiveCapability: (token: string) => boolean;
|
|
157
165
|
/** The connection deadlines and caps; production passes `CONNECT_LIMITS`. */
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
* - identity and configuration-profile resolution and farm sync (`resolveDecisions`, `resyncFarm`, `buildEntryFacts`, ...), pure over facts and ports passed in;
|
|
5
5
|
* - routing: the front door's Remote-Control-preserving, capability-authenticated CONNECT surface and its certificate authority, the front-door supervisor and ensure lifecycle, and the headroom supervisor and ensure lifecycle, each pure over its injected ports;
|
|
6
6
|
* - the ambient-credential guard;
|
|
7
|
-
* - the per-identity usage snapshot a statusline or launcher reads: its schema and the reader over an injected filesystem
|
|
7
|
+
* - the per-identity usage snapshot a statusline or launcher reads: its schema and the reader over an injected filesystem;
|
|
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.
|
|
8
9
|
*
|
|
9
10
|
* Everything the CLI alone needs (commander wiring, prompts, `doctor`, `check`) is deliberately not exported here.
|
|
10
11
|
*/
|
|
11
12
|
export { resolveDecisions, topLevelNames, type ResolveDecisionsInput, type ResolvedState } from "./resolve/pipeline";
|
|
12
13
|
export type { CompiledRule, Decision, Diagnostic, EliminatedRule, EntryFact, EntryFacts, FlattenedCascade, Layer, LayerId } from "./resolve/types";
|
|
13
14
|
export { buildEntryFacts, carryOver, FARM_MANIFEST_FILENAME, readFarmManifest, recoverFarm, recoveryDiagnostics, resyncFarm, type BuildEntryFactsParams, type CarryOverParams, type CarryOverResult, type RecoverFarmParams, type RecoveryResult, type ResyncFarmParams, type ResyncFarmResult, } from "./launcher/farm";
|
|
14
|
-
export { CONNECT_INTERCEPT_HOST, CONNECT_LIMITS, createLeafCache, ensureCa, forwardableHeaders, generateCa, isInterceptedHost, mintLeaf, parseConnectTarget, realConnectCertStore, realConnectEffects, ROUTED_PATH_PREFIX, servedByPipeline, startConnectServer, type CaMaterial, type ConnectCertStore, type ConnectEffects, type ConnectLimits, type ConnectServerConfig, type ConnectServerHandle, type ConnectTarget, type LeafCert, } from "./frontdoor/connect";
|
|
15
|
+
export { CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, createLeafCache, ensureCa, forwardableHeaders, generateCa, isInterceptedHost, mintLeaf, parseConnectTarget, realConnectCertStore, realConnectEffects, ROUTED_PATH_PREFIX, servedByPipeline, startConnectServer, type CaMaterial, type ConnectCertStore, type ConnectEffects, type ConnectLimits, type ConnectServerConfig, type ConnectServerHandle, type ConnectTarget, type LeafCert, } from "./frontdoor/connect";
|
|
15
16
|
export { ensureFrontDoor, FrontDoorStartError, type EnsureFrontDoorPorts } from "./frontdoor/ensure";
|
|
16
17
|
export { runFrontDoorSupervisor, type FrontDoorSupervisorPorts, type RunFrontDoorSupervisorOptions } from "./frontdoor/supervisor";
|
|
17
18
|
export { listUsageSnapshots, readUsageSnapshot, snapshotPath, UsageSnapshotError, type UsageReadFs } from "./usage/read";
|
|
@@ -19,3 +20,6 @@ export { UsageSnapshotSchema, type UsageSnapshot } from "./usage/schema";
|
|
|
19
20
|
export { ensureHeadroom, HeadroomStartError, type EnsureHeadroomPorts } from "./headroom/ensure";
|
|
20
21
|
export { resolveSupervisorConfig, runSupervisor, type HeadroomSupervisorConfig, type RunSupervisorOptions, type SupervisorPorts } from "./headroom/supervisor";
|
|
21
22
|
export { AMBIENT_CREDENTIAL_VARS, detectAmbientCredential, evaluateAmbientCredentialGuard, formatAmbientCredentialGuardMessage, type AmbientCredentialDetection, type AmbientCredentialGuardResult, type AmbientCredentialVar, type EvaluateAmbientCredentialGuardParams, type InjectedCredential, } from "./launcher/guard";
|
|
23
|
+
export { buildLayoutPaths, resolveAgentShimHome, resolveClaudeHome, resolveLayoutPaths, type LayoutPaths } from "./paths";
|
|
24
|
+
export { CliError, EXIT_FAILURE, EXIT_USAGE, UsageError } from "./cliError";
|
|
25
|
+
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";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.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>",
|