Changelog
[0.4.3] - 2026-04-14
Fixed
WithProxynow covers OAuth token refresh, not just/v1/messagesand the initial profile fetch. Previously the refresh call inside the built-in token managers (WithToken,WithTokenFile,WithEnvToken) went through the package-levelauthHTTPClient(defaulting tohttp.DefaultClient), which ignored the Client's proxy configuration and producedHTTP 403from regions where a direct connection toplatform.claude.com/v1/oauth/tokenis blocked. AfterNewClientresolves the per-ClientHTTPClient, it is now propagated into the token manager so every subsequent refresh reuses the same transport — a singleWithProxy(...)call is enough to route all outbound traffic of a Client instance. Callers no longer need to pairWithProxywithNewProxiedHTTPClient+SetAuthHTTPClient. The package-levelSetAuthHTTPClient/authHTTPClientremain in place for standalone auth helpers that run without a Client (Login,LoginManual, top-levelFetchProfile).
Changed
refreshAccessTokenis now parameterised by*http.Client. Whennil, it falls back to the package-levelauthHTTPClient— preserving the previous behaviour for any direct caller — but all internal call sites pass the per-Client HTTPClient.tokenManagerandenvTokenManagercarry anhttpClientfield, populated byNewClient.WithTokenProvider-supplied providers remain the caller's responsibility: the wiring only applies to the library's built-in managers.
[0.4.2] - 2026-04-14
Fixed
ContentBlock.Contentis now a pointer (*Content) soomitemptyactually drops the field when it is not set. Previouslytextandtool_useblocks serialised an emptycontent: ""property, which Anthropic rejected withHTTP 400 "Extra inputs are not permitted".ToolResultBlockstill emits a non-empty*Content; regression coverage inTestContentBlock_NoEmptyContentandTestToolResultBlock_MarshalsContent.
[0.4.1] - 2026-04-13
Fixed
- OAuth requests to
/v1/messagesnow prepend the Claude Code identity preamble (You are Claude Code, Anthropic's official CLI for Claude.) as the first system block. The server-side gate onapi.anthropic.comchecks for this exact opening line and, when missing, rejects OAuth requests withHTTP 403 forbidden: Request not allowedeven when billing and beta headers are otherwise valid. User-supplied system prompts (string or blocks) are preserved verbatim after the two prefix blocks (identity → billing → user).
[0.4.0] - 2026-04-13
Added
- Proxy support, end-to-end for both API and OAuth traffic. New option
WithProxy(url)and public helperNewProxiedHTTPClient(url). Supported schemes:http,https,socks5,socks5h. Credentials in the URL are used as Basic proxy auth. With no option, the client automatically honorsHTTPS_PROXY/ALL_PROXYfrom the environment;WithProxy("")is an explicit opt-out that forces a direct connection. HTTP/HTTPS proxies are handled via an in-houseCONNECTtunnel built on top of uTLS, so the Chrome TLS fingerprint is preserved end-to-end regardless of proxy type. - Global CLI flag
--proxy URL— applies to every subcommand (login,usage,query,stream). Also installed for OAuth endpoints (viaSetAuthHTTPClient) sokraube login --proxy ...routes through the proxy too. SetAuthHTTPClient(c *http.Client)— swap the package-level HTTP client used by standalone OAuth flows (LoginManual, token refresh/exchange,FetchProfile). Passnilto restorehttp.DefaultClient.- Detailed error diagnostics. On any non-2xx response the client now emits a single
api: error responselog entry withmethod, fullurl,status,elapsed,local_addr,remote_addr,proxy(redacted), request headers (withAuthorization/Cookie/Proxy-Authorization/Set-Cookieredacted), request body, response headers, and response body — each bounded to 8 KB so large payloads don't flood stderr. Transport-level failures emit an analogousapi: request failedentry. Response bodies on error paths are buffered in memory and re-exposed throughresp.Body, so existing decoders continue to work transparently. - Egress visibility. Successful responses and transport handshakes now log
local_addr/remote_addr/proxyat debug level — useful when debugging multi-homed hosts, split proxies, or provider-side IP gating.
Changed
APIError.Error()now renders asHTTP <status> <type>: <message>when the HTTP status is known, so the numeric code is always visible without a type assertion. WhenStatus == 0, the legacy<type>: <message>form is preserved.Client.fetchProfile(called byNewClient) now routes throughc.HTTPClient, soWithProxyautomatically applies to the profile request alongside/v1/messages.chromeTransportswitches from a barenet.Dialto a context-awarenet.Dialer.DialContextwith a 30s timeout — respectsctxcancellation and avoids hangs on silent networks.
[0.3.0] - 2026-04-12
Breaking
- Credentials are now stored as JSON at
~/.config/kraube/credentials.json(refreshToken+accessToken+expiresAt). The old plain-text~/.config/kraube/tokenis no longer read — re-runkraube loginafter upgrading. - Removed
SaveToken,LoadToken,DefaultTokenPath. UseSaveCredentials,LoadCredentials,DefaultCredentialsPathand the newCredentialsstruct. Login/LoginManualnow return*Credentialsinstead ofstring.
Added
- Multi-process safety:
WithTokenFilecoordinates refresh via an OS-level file lock (flock(2)on Linux/macOS,LockFileExon Windows), with read-after-lock semantics. Parallel processes on one machine share a single rotation. KRAUBE_CREDENTIALS_PATHenvironment variable: honored by both the CLI andWithTokenFile("").- CLI flag
--out PATHonkraube login. Credentials.IsAccessLive()helper.
Changed
WithToken(refreshToken)is now explicitly in-memory only — rotation is not persisted. UseWithTokenFilefor persistence and parallelism.
[0.2.0] - 2026-04-04
Breaking
TokenProviderinterface returns(string, error)instead of(*Credentials, error)- Removed
Credentialsstruct — replaced with single "token" concept - New options:
WithToken,WithTokenFilereplace old credential options - Token stored as plain text in
~/.config/kraube/token
Added
- Real-time streaming events:
Event(),EventType(),CurrentBlock() StreamEventinterface for typed event handling via type switch- Unit test suite covering auth, providers, streaming, types, rate limits
- CLI real-time text output in
kraube stream
Changed
- Simplified authentication: one token, access tokens managed in memory
- Updated all documentation
[0.1.0] - 2026-04-04
Added
- Stateless
TokenProviderinterface for flexible authentication - Functional options pattern:
NewClient(ctx, ...Option)as single entry point - Built-in providers: Token, TokenFile, EnvToken, Callback
README.mdwith full usage guide and brand assets- GitHub Actions CI/CD (lint, test, release)
- GoReleaser configuration for cross-platform CLI builds
- Documentation site with VitePress
LICENSE(MIT)
Changed
- Rebranded to Kraube API (
scott-walker/kraube-api) - OAuth-only by design — removed API key support
- Single
NewClientconstructor replaces three old constructors
[0.0.0] - 2026-04-04
- Initial commit: OAuth PKCE flow, Messages API, streaming, tool use
- Chrome TLS fingerprint via uTLS
- Billing header and metadata injection
- Rate limit tracking and persistence
- CLI: login, query, stream, usage
