claude-use 4.5.0 → 5.0.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 -1
- package/dist/cli.cjs +3365 -2594
- package/dist/index.cjs +472 -159
- package/dist/index.mjs +462 -153
- package/dist/types/frontdoor/capability.d.ts +19 -0
- package/dist/types/frontdoor/connect.d.ts +179 -0
- package/dist/types/frontdoor/ensure.d.ts +34 -0
- package/dist/types/frontdoor/probe.d.ts +13 -0
- package/dist/types/frontdoor/state.d.ts +32 -1
- package/dist/types/frontdoor/supervisor.d.ts +48 -0
- package/dist/types/headroom/ensure.d.ts +1 -2
- package/dist/types/headroom/state.d.ts +2 -4
- package/dist/types/headroom/supervisor.d.ts +1 -6
- package/dist/types/index.d.ts +4 -2
- package/dist/types/launcher/ports.d.ts +22 -10
- package/dist/types/paths.d.ts +8 -6
- package/package.json +1 -1
- package/dist/types/headroom/mitm.d.ts +0 -138
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
-
import * as net from "node:net";
|
|
3
|
-
/**
|
|
4
|
-
* A CONNECT proxy the headroom supervisor runs as a second server in its own process, so an OAuth session can have headroom's compression AND Claude Code's Remote Control at once: Remote Control refuses any `ANTHROPIC_BASE_URL` other than the real API, but happily honours `HTTPS_PROXY`, so OAuth launches route at the proxy layer instead.
|
|
5
|
-
*
|
|
6
|
-
* Every CONNECT target is blind-tunnelled byte for byte EXCEPT the intercept host (Claude Code's own API), whose TLS this proxy terminates with a leaf certificate signed by a locally generated CA. On the terminated session, paths headroom serves are forwarded to headroom's existing loopback port over plain HTTP (compression, per-session stats, and upstream auth unchanged; the client's Authorization header passes through untouched), and every other path is piped by this proxy to the real upstream over TLS, so Remote Control's streaming, OAuth refreshes, and unknown endpoints bypass headroom entirely.
|
|
7
|
-
*/
|
|
8
|
-
/** The one CONNECT host whose TLS gets terminated: Claude Code's own API, the upstream headroom compresses. */
|
|
9
|
-
export declare const MITM_INTERCEPT_HOST = "api.anthropic.com";
|
|
10
|
-
/** Paths under this prefix are what headroom serves; everything else on the terminated session goes to the real upstream. */
|
|
11
|
-
export declare const HEADROOM_SERVED_PATH_PREFIX = "/v1/";
|
|
12
|
-
/** 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. */
|
|
13
|
-
export declare const HTTPS_PORT = 443;
|
|
14
|
-
/** One parsed CONNECT authority, the host lowercased and the port defaulted. */
|
|
15
|
-
export interface ConnectTarget {
|
|
16
|
-
readonly host: string;
|
|
17
|
-
readonly port: number;
|
|
18
|
-
}
|
|
19
|
-
/** Parses a CONNECT authority (`host:port`, or a bare `host` meaning 443), or undefined when it names no host or a non-numeric port. */
|
|
20
|
-
export declare function parseConnectTarget(authority: string): ConnectTarget | undefined;
|
|
21
|
-
/** Whether a CONNECT target's host (port already stripped) is the one whose TLS this proxy terminates. */
|
|
22
|
-
export declare function isInterceptedHost(host: string, interceptHost: string): boolean;
|
|
23
|
-
/** Whether a request path on the terminated session is one headroom serves. The query string stays part of the path: `/v1/messages?beta=true` is still headroom's. */
|
|
24
|
-
export declare function servedByHeadroom(path: string | undefined): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Headers a forwarded HTTP message keeps: everything except the hop-by-hop set, which belongs to whichever connection carried it and must not leak onto the next one. The `Connection` header's own value can name further hop-by-hop headers (RFC 9110 section 7.6.1), so those go too. Returns a fresh object; the input is the live parser's map and is never mutated.
|
|
27
|
-
*/
|
|
28
|
-
export declare function forwardableHeaders(headers: Readonly<IncomingHttpHeaders>): IncomingHttpHeaders;
|
|
29
|
-
/** A CA certificate and its private key, both as PEM. */
|
|
30
|
-
export interface CaMaterial {
|
|
31
|
-
readonly certPem: string;
|
|
32
|
-
readonly keyPem: string;
|
|
33
|
-
}
|
|
34
|
-
/** A TLS leaf certificate and its private key, both as PEM. */
|
|
35
|
-
export interface LeafCert {
|
|
36
|
-
readonly certPem: string;
|
|
37
|
-
readonly keyPem: string;
|
|
38
|
-
}
|
|
39
|
-
/** Generates the local CA: one RSA keypair, self-signed, CA-only by basicConstraints and keyUsage, with a random serial. Pure node-forge, no openssl, so the same code works on every platform claude-use ships to. */
|
|
40
|
-
export declare function generateCa(now: Readonly<Date>): CaMaterial;
|
|
41
|
-
/** Mints the TLS leaf for one host, signed by the CA: its own RSA keypair, the host in the SAN, server-auth usage only. */
|
|
42
|
-
export declare function mintLeaf(ca: CaMaterial, host: string, now: Readonly<Date>): LeafCert;
|
|
43
|
-
/** Mints each host's leaf once from the CA and reuses it, because a 2048-bit keypair in pure JS costs seconds and nothing about the certificate changes between sessions. */
|
|
44
|
-
export declare function createLeafCache(ca: CaMaterial, now: () => Date): (host: string) => LeafCert;
|
|
45
|
-
/**
|
|
46
|
-
* Persistence for the CA: generated once on the machine's first headroom start and reused forever after, because regenerating it would invalidate every child's `NODE_EXTRA_CA_CERTS` pointing at the old file. The real implementation writes the key with mode 0600; injected fakes keep it in memory.
|
|
47
|
-
*/
|
|
48
|
-
export interface MitmCertStore {
|
|
49
|
-
/** The persisted CA, or undefined when none exists yet (or only half of it does: a cert without its key can sign nothing, so it counts as absent). */
|
|
50
|
-
readonly loadCa: () => CaMaterial | undefined;
|
|
51
|
-
/** Persists both halves of the CA, the key unreadable to other users. */
|
|
52
|
-
readonly writeCa: (ca: CaMaterial) => void;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Loads the persisted CA, generating and persisting one when no usable CA exists. A stored pair that node-forge cannot parse is treated as absent and replaced: a truncated write is the one failure mode a regeneration can actually repair, and every child that trusted the old file needs a new `NODE_EXTRA_CA_CERTS` anyway once its CA stops parsing.
|
|
56
|
-
*/
|
|
57
|
-
export declare function ensureCa(store: MitmCertStore, generate: () => CaMaterial): CaMaterial;
|
|
58
|
-
/** Where one forwarded request goes, and how. Headroom's loopback port is plain HTTP; the real upstream is TLS. */
|
|
59
|
-
interface MitmForwardTarget {
|
|
60
|
-
readonly host: string;
|
|
61
|
-
readonly port: number;
|
|
62
|
-
readonly tls: boolean;
|
|
63
|
-
/** The SNI name to present; defaults to `host`. Separated so a test can connect to a local fake while presenting the production hostname. */
|
|
64
|
-
readonly servername?: string;
|
|
65
|
-
/** Extra trust anchors for the target's certificate, when it is not system-trusted (a test's local fake upstream). */
|
|
66
|
-
readonly ca?: readonly string[];
|
|
67
|
-
/** Overrides certificate verification; production leaves it at the Node default (verify against system trust or `ca`). */
|
|
68
|
-
readonly rejectUnauthorized?: boolean;
|
|
69
|
-
}
|
|
70
|
-
/** Handles one parsed HTTP request on a terminated TLS session. */
|
|
71
|
-
type MitmRequestHandler = (request: IncomingMessage, response: ServerResponse) => void;
|
|
72
|
-
/** A bound loopback listener and how to stop it. */
|
|
73
|
-
interface MitmListenerHandle {
|
|
74
|
-
readonly port: number;
|
|
75
|
-
/** Stops accepting, ends every live connection, and resolves once the port is released. */
|
|
76
|
-
readonly close: () => Promise<void>;
|
|
77
|
-
}
|
|
78
|
-
/** Presents one leaf's server-side TLS on CONNECTed sockets. */
|
|
79
|
-
interface TlsAcceptor {
|
|
80
|
-
/** Starts the TLS handshake on a socket that has just received its CONNECT response. */
|
|
81
|
-
readonly accept: (socket: net.Socket) => void;
|
|
82
|
-
/** Drops every session this acceptor is terminating. */
|
|
83
|
-
readonly close: () => void;
|
|
84
|
-
}
|
|
85
|
-
/** Parses HTTP over terminated sockets and serves each request through the handler, keep-alive included. */
|
|
86
|
-
interface HttpParserSession {
|
|
87
|
-
readonly serve: (socket: net.Socket) => void;
|
|
88
|
-
readonly close: () => void;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Every effect the MITM proxy performs, injected so the routing decisions and lifecycle run against fakes in unit tests (the SupervisorPorts pattern): TCP listening, TLS termination, HTTP parsing, plain TCP tunnels, and request forwarding. The real implementation is `realMitmEffects`; the TLS round-trip test uses it with redirected targets.
|
|
92
|
-
*/
|
|
93
|
-
export interface MitmEffects {
|
|
94
|
-
/** Binds a loopback TCP listener; `preferredPort` is tried first and any free port used when it is taken (bind, do not probe: check-then-bind races). Resolves with the bound port and a close handle. */
|
|
95
|
-
readonly listenLoopback: (preferredPort: number | undefined, onSocket: (socket: net.Socket) => void) => Promise<MitmListenerHandle>;
|
|
96
|
-
/** Builds the TLS terminator for one leaf, handing each successfully handshaked session to `onSecure`. */
|
|
97
|
-
readonly createTlsAcceptor: (leaf: LeafCert, onSecure: (secure: net.Socket) => void) => TlsAcceptor;
|
|
98
|
-
/** Builds the HTTP parser bound to one request handler. */
|
|
99
|
-
readonly createHttpSession: (handler: MitmRequestHandler) => HttpParserSession;
|
|
100
|
-
/** Opens a raw TCP connection for a blind tunnel. */
|
|
101
|
-
readonly connectTcp: (host: string, port: number) => Promise<net.Socket>;
|
|
102
|
-
/** Streams one request to `target` and the response back, never buffering a body. */
|
|
103
|
-
readonly forwardHttp: (target: MitmForwardTarget, request: IncomingMessage, response: ServerResponse) => void;
|
|
104
|
-
}
|
|
105
|
-
/** Everything the proxy needs to route, resolved before it starts. */
|
|
106
|
-
export interface MitmServerConfig {
|
|
107
|
-
/** The CONNECT host whose TLS gets terminated. */
|
|
108
|
-
readonly interceptHost: string;
|
|
109
|
-
/**
|
|
110
|
-
* Headroom's loopback port, read per request rather than captured at start-up: the daemon can crash and restart on a different port while this proxy keeps listening, and headroom-served paths must follow it. While it reads undefined (the restart window), headroom-served paths fail fast with 502 rather than silently bypassing headroom to the real upstream.
|
|
111
|
-
*/
|
|
112
|
-
readonly headroomPort: () => number | undefined;
|
|
113
|
-
/** The leaf to terminate `interceptHost` with, minted and cached per host. */
|
|
114
|
-
readonly leafFor: (host: string) => LeafCert;
|
|
115
|
-
/** Where non-headroom paths on the terminated session are piped: the real upstream over TLS. */
|
|
116
|
-
readonly upstream: MitmForwardTarget;
|
|
117
|
-
}
|
|
118
|
-
/** A running MITM proxy. */
|
|
119
|
-
export interface MitmServerHandle {
|
|
120
|
-
readonly port: number;
|
|
121
|
-
/** Stops the listener, drops every live tunnel and terminated session, and resolves once the port is released. */
|
|
122
|
-
readonly close: () => Promise<void>;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Starts the MITM proxy: binds the listener, mints the intercept host's leaf, and wires the per-connection routing. Resolves once the listener is bound.
|
|
126
|
-
*
|
|
127
|
-
* The connection flow: read the CONNECT head (never more of the stream than that, so an early ClientHello glued to the head is pushed back with `unshift` and still seen by whatever consumes the socket next), then either blind-tunnel the target or terminate its TLS and parse HTTP on the session. Every effect flows through `effects`; nothing here touches the network or filesystem itself.
|
|
128
|
-
*/
|
|
129
|
-
export declare function startMitmServer(config: MitmServerConfig, effects: MitmEffects, preferredPort: number | undefined): Promise<MitmServerHandle>;
|
|
130
|
-
/** The real `MitmEffects` over node's own net, tls, and http. `connectTcp` opens real connections to the CONNECTed host, so tests that want a blind tunnel redirect it. */
|
|
131
|
-
export declare function realMitmEffects(): MitmEffects;
|
|
132
|
-
/** The real `MitmCertStore` on the filesystem: `ca.pem` world-readable (it is public material), `ca.key` mode 0600 exactly, chmod'ed after the write because a create's mode bits pass through the process umask. */
|
|
133
|
-
export declare function realMitmCertStore(paths: {
|
|
134
|
-
readonly headroomCaDir: string;
|
|
135
|
-
readonly headroomCaCertFile: string;
|
|
136
|
-
readonly headroomCaKeyFile: string;
|
|
137
|
-
}): MitmCertStore;
|
|
138
|
-
export {};
|