This repo is a CortexKit-maintained Anthropic auth monorepo for OpenCode and Pi. The OpenCode package is a fork of the original @ex-machina/opencode-anthropic-auth plugin, so older entries below the initial CortexKit release are inherited from upstream package history.
- Keep deterministic Opus 4.8 recovery armed as a backstop when Anthropic's server-side safety policy still returns a refusal, while stripping the server-fallback opt-in from source-model prewarms.
- Preserve completed tool calls when a served fallback later refuses, continuing with the existing tool result instead of replaying potentially non-idempotent tools.
- Default eligible OpenCode Fable 5 and Opus 5 OAuth requests to Anthropic's server-side safety fallback, preserve fallback conversation boundaries across stored history, and report active/restored model transitions in the TUI sidebar and OpenCode Desktop.
- Keep the previous deterministic 10-response Opus 4.8 recovery available through
OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE=legacy, including source-model cache prewarming and standby cache bridges.
- Reconcile Desktop fallback notices against live OpenCode session status when a delayed cache warm completes after the normal completion/idle events.
- Strip trailing whitespace-only text blocks after the latest assistant tool call before Anthropic replay, preventing valid tool-result continuations from being rejected as unsupported assistant prefills.
- Add Claude Opus 5 request shaping to OpenCode and Pi's converter, including summarized adaptive thinking, effort-based reasoning, explicit disabled-thinking handling, and OpenCode fast mode.
- Extend OpenCode content-filter recovery to Opus 5: temporarily downgrade refused requests to Opus 4.8 for 10 successful responses while preserving the selected model, prewarming the original Opus 5 cache, and reporting model-specific recovery transitions.
- Publish native OpenCode Opus 5
low,medium,high,xhigh, andmaxeffort variants instead of inherited manual-thinking budgets. - Isolate Fable 5 and Opus 5 recovery state, cache warm chains, OAuth account binding, and standby anchors by session and source-model family.
- Treat Darwin/Bun
EINVALduring a contended eviction-marker create as a lost lock race, preventing high-contention refresh-lock failures.
Thanks to @iceteaSA for the Opus 5 contribution.
- Refresh OAuth 5h and 7d quota from genuine
anthropic-ratelimit-unified-*response headers across direct, HTTP relay, and WebSocket relay transports while preserving poll-owned model-scoped quota data. - Show account plan/tier metadata, the binding quota window, extra-usage credit status, and Anthropic fallback hints in expanded OpenCode quota and account surfaces.
- Prevent startup, quota-refresh, metadata, and command writes from overwriting another process's active sidebar route by preserving routing-authoritative fields behind cross-process locked and fenced state writes.
- Token-fence asynchronous account-profile persistence so delayed profile fetches or clears cannot restore stale credentials or remove a newer profile.
Thanks to @iceteaSA for the quota surfaces, relay harvesting, and sidebar-state contributions.
- Add
sticky-balancedrouting for OpenCode and Pi, assigning cold sessions by current quota headroom while preserving account affinity across processes, restarts, transient failures, short reset holds, model-scoped limits, and Fable recovery. - Add
/claude-cachekeep alwaysand aggregate live tracked-session status across OpenCode project plugin instances and Pi processes without sharing request bodies, credentials, or headers.
- Prevent concurrent fallback-account additions and configuration saves from dropping accounts by serializing cross-process writes, merging current disk state, and using explicit removal semantics.
- Preserve fresh empty model-scoped quota snapshots and evaluate scoped quota freshness independently during sticky routing.
- Bound request-dump storage to 512 MB by default and harden end-to-end process and temporary-directory cleanup.
Thanks to @iceteaSA for the dump-storage and end-to-end cleanup contribution.
- Show Fable recovery transition notices immediately during active multi-step OpenCode Desktop runs while preserving the selected session model and preventing additional provider turns.
- Restore live OpenCode TUI sidebar updates on current OpenTUI hosts by shipping a precompiled reactive Solid tree, with packed-package smoke coverage in CI and release gates.
Thanks to @tomolom for reporting the TUI packaging issue.
- Add automatic OpenCode recovery for Fable content-filter refusals: transparently route the session through Opus 4.8 for a 10-response recovery window, prewarm Fable after each successful Opus response, and return to Fable without changing the selected session model.
- Preserve both model caches during recovery by warming Fable with the OAuth account that served the refused request and retaining an Opus standby cache bridge when healthy Fable turns move the previous Opus boundary outside Anthropic's 20-block lookback.
- Show session-specific recovery status in the OpenCode TUI sidebar and send safe transition notices in OpenCode Desktop without spending quota or creating an extra provider response.
- Expose Claude Sonnet 5 in the Pi Anthropic provider catalog, completing its existing adaptive-thinking request support.
- Preserve empty model-scoped quota arrays through account-state loading, runtime-state merges, and sidebar normalization so a fresh quota response can clear a previously stored scoped window.
- Omit unavailable 5h/7d placeholders from collapsed quota summaries when only a scoped model window is present.
- Update OpenTUI Solid, OpenCode SDK, Biome, and generated project documentation.
Thanks to @iceteaSA for the scoped-quota persistence fixes and @nodnarbnitram for the Pi Sonnet 5 catalog contribution.
- Add model-scoped OAuth quota support for Anthropic weekly scoped limits such as Fable, including sidebar/quota-summary display, model-aware OAuth fallback routing, and Pi parity. Fable scoped exhaustion can route Fable requests to an OAuth fallback while other models continue using the main account.
- Add per-model scoped killswitch thresholds so matching scoped quota windows can hard-block an account without poisoning routing for other models.
- Fix same-label fallback OAuth re-login state merging so fresh credentials clear stale reauth/quota errors and invalidate old quota cache entries.
- Keep CacheKeep tracking on OAuth fallback routes and prewarm with the same OAuth account that served the cached request.
- Shorten the Fable scoped quota sidebar label to
Faand preserve scoped killswitch thresholds in the OpenCode TUI edit modal.
Thanks to @iceteaSA for the scoped killswitch contribution.
- Update OpenCode, Pi, Biome, and Miniflare dependencies.
- Request visible summarized adaptive thinking for Claude Sonnet 5 in OpenCode and Pi, while preserving explicit disabled-thinking requests on OpenCode's raw Anthropic body path.
Thanks to @iceteaSA for the Sonnet 5 adaptive-thinking fix.
- Handle Anthropic auth slash commands with an Effect-compatible
204 No Contentresponse shape, matching OpenCode's current command-interception path while keeping the legacy sentinel fallback for older hosts.
- Add interactive account-management and logging flows for OpenCode and Pi, including fallback account list/enable/disable/reorder/remove actions, API-key route setup, OAuth fallback login helpers, and persisted log-level settings.
- Add shared leveled redacting rotating logging, CacheKeep per-warm cost logging, and an opt-in CacheKeep subagent toggle.
- Harden account storage and refresh coordination with serialized account-store updates, stale-lock re-election fixes, safer atomic writes, malformed sidebar-state guards, RPC multi-session isolation, and runtime-state loading when the editable config file is absent.
- Improve account cleanup and re-login UX by clearing removed fallback runtime state, showing dead fallback accounts that need re-login, and preserving clearer OAuth account labels.
- Treat Claude quota endpoint
403responses as account/org-policy auth failures without arming quota backoff or OAuth refresh backoff. - Update OpenCode, OpenTUI, Pi, Miniflare, Biome, GitHub Actions, and related development dependencies.
Thanks to @iceteaSA for the account/logging parity work and account-management fixes, @jonmast for the runtime-state load fix, and @eddieparc for reporting and proposing the quota 403 backoff boundary fix.
- Keep OpenCode
fallback-firstrouting on usable fallback accounts when another process is already refreshing fallback quota, preventing a broken primary OAuth refresh backoff from aborting requests while fallback quota is still passing. - Keep the OpenCode TUI preferences watcher stable even when unrelated tests or integrations temporarily override global timers.
- Update Biome to 2.5.0.
- Fix OpenCode
ReadableStream is lockedfailures after detecting Anthropic streaming rate-limit errors when no fallback route can serve the request, returning a replayable inspected response instead of reusing the consumed stream.
- Stabilize
/claude-cache hybridsystem cache anchors when OpenCode leaves plugin-added system instructions split across multiple blocks, preserving the canonical merged tail before placing the Anthropic cache breakpoint.
- Add interactive OpenCode TUI command dialogs for Anthropic auth commands, backed by a localhost-only authenticated RPC bridge so sidebar actions can configure routing, cache, quota, relay, and related settings without text-only command replies.
- Mark transient Anthropic SSE server errors inside HTTP 200 streams as retryable connection-reset-style failures so OpenCode can use its normal auto-retry flow instead of surfacing them as non-retryable unknown errors.
Thanks to @iceteaSA for the interactive TUI command modal contribution.
- Align Claude OAuth request fingerprints with captured Claude Code 2.1.177 interactive CLI traffic, including the CLI identity string, user agent, billing
cc_entrypoint=cli, and beta header ordering. - Remove unavailable
context-1mandeffortbetas from Claude Code OAuth requests, add the captured thinking token count beta, and keep redacted thinking disabled by design. - Match captured OAuth login/refresh details more closely with the updated axios-style user agent, accept header, refresh scope, and Claude Max authorize URL.
Thanks to @iceteaSA for the Claude Code MITM capture and fingerprint alignment.
- Keep OpenCode sidebar quota display stable during concurrent quota refreshes by re-seeding from the latest runtime state and avoiding stale quota writes from older plugin instances.
- Dump direct Anthropic requests when
/claude-dump onis enabled, including redacted request metadata for OpenCode and Pi direct/API paths. Relay requests continue to include relay metadata. - Harden Pi SSE reader cleanup so preflight parsing cannot cancel the response stream on early abandon.
- Strip OpenAI encrypted reasoning payloads, including Pi JSON-stringified
encrypted_contentpayloads, before converting history to Anthropicthinkingblocks. - Repair Pi replay after interrupted tool calls by dropping incomplete aborted assistant
tool_useturns and orphan tool results before sending Anthropic history. - Add configurable OpenCode TUI preferences via
tui-preferences.jsonc, persisted sidebar collapse state, sharedforceToTopordering helpers, and quota pacing/runout projections in the sidebar. - Update OpenCode, Pi, OpenTUI, Miniflare, and related development dependencies.
Thanks to @iceteaSA for the TUI preferences and quota pacing contributions.
- Fix
/claude-cache hybridanchors for Magic Context requests where stable project context and session history are merged intomessages[0], preserving cache breakpoints on the first two prefix blocks instead of the volatile tail.
- Request summarized adaptive thinking for Claude Fable 5 and Mythos 5 so agents can display readable reasoning summaries instead of blank signed-thinking blocks.
- Add opt-in structural SSE diagnostics under
OPENCODE_ANTHROPIC_AUTH_PERF=1, counting Anthropic event, block, and delta types without logging response text or tool input content.
- Add an OpenCode
costZeroing.enabledopt-out so advanced users can show Anthropic model pricing for OAuth sessions instead of the default zero-cost subscription/quota display.
- Fix synthetic Claude Fable 5 and Mythos 5 OpenCode catalog entries so
model.api.idmatches the selected model, ensuring the wire request sends Fable/Mythos rather than the cloned Opus fallback model. - Coalesce WebSocket relay upstream SSE chunks before binary WebSocket sends, reducing tiny frame fragmentation while preserving response bytes exactly.
- Memoize repeated system-prompt sanitation work with a bounded byte-aware cache.
- Add Claude Fable 5 and limited-access Claude Mythos 5 support across shared model metadata, OpenCode's Anthropic provider catalog, Pi's provider catalog, and the cache-usage analyzer.
- Add API-key fallback routes for Anthropic-compatible providers such as Kie, with route secrets stored in runtime state and API-key spending gated behind fresh, token-bound confirmation that main OAuth quota is exhausted.
- Split editable sidecar config from volatile auth runtime state so background refresh, quota, and routing writers cannot overwrite user configuration such as quota intervals or relay settings.
- Normalize Fable/Mythos OpenCode requests by removing top-level adaptive
thinkingand preservingoutput_config.effort, matching Anthropic's migration guidance. - Show both 5-hour and 7-day quota windows in the collapsed OpenCode sidebar active-account summary.
- Display Anthropic OAuth models as zero-cost in OpenCode through the provider model hook while preserving token accounting and API-key model pricing.
- Bound relay/cachekeep/identity in-memory caches, propagate relay abort signals, improve Pi stream cancellation, and document intentional relay tradeoffs in
AUDITOR.md. - Add opt-in performance instrumentation for Anthropic request rewriting, relay payloads, and downstream stream consumption under
OPENCODE_ANTHROPIC_AUTH_PERF=1.
- Improve
/claude-cache hybridfor Magic Context sessions whose stablem[0]and volatilem[1]history blocks are merged into one Anthropic user message: hybrid mode now anchors both the first and last cacheable block ofmessages[0]so stable leading history can remain cached when the trailing delta changes. - Include a sanitized session/affinity segment in
/claude-dumpartifact filenames so dumps from different sessions are easier to find.
- Refresh current-token main quota in the OpenCode sidebar without blocking
fallback-firstrouting, avoiding a stalechecking…display after main token rotation. - Keep custom/future Claude billing version suffixes stable across date boundaries so the billing header does not rotate at midnight and unexpectedly bust prompt-cache prefixes.
- Mark WebSocket relay stream-close failures as retryable connection resets so OpenCode can use its normal retry UI instead of treating mid-stream relay disconnects as terminal unknown errors.
- Add
/claude-killswitchfor OpenCode, allowing requests to be hard-blocked or rerouted when main or fallback Claude quota drops below configured per-account thresholds. - Add a collapsible OpenCode quota sidebar view and opt-in quota refresh toasts controlled by
quota.showToasts.
- Improve WebSocket relay recovery when a socket closes after upstream
response_startbut before any stream bytes reach OpenCode, and add clearer close diagnostics for mid-stream failures. - Harden Pi Anthropic message conversion for tool-result and content-shape edge cases.
- Fix OpenCode sidebar quota refreshes so async quota updates do not clobber the active account or show stale fallback quota state.
- Update OpenCode SDK/plugin, OpenTUI, and relay test dependencies.
Thanks to @iceteaSA for the killswitch, quota toast, sidebar, and Pi conversion contributions.
- Add an OpenCode TUI sidebar for Claude quota, active route, relay transport, and cache status.
- Add a shared quota manager with persisted quota caching, quota API backoff, token-bound fallback quota state, and request-count-based quota refreshes.
- Strip trailing assistant messages from Anthropic request bodies to avoid Claude OAuth prefill
400errors when a conversation does not end with a user message. - Avoid placing
cache_controlon message objects in hybrid cache mode when the selected message has no cacheable content block. - Invalidate fallback quota cache and quota backoff when a same-label fallback account is re-logged with a new token.
- Fix OpenCode TUI package loading by exporting the source TUI entrypoint and including required sidebar state files in the package.
- Fix TUI sidebar state so it uses token-bound quota reads and reflects the actual active route.
- Canonicalize dropped AFT tool namespaces in Anthropic responses, so
safety/mcp_Safetyand other known AFT suffixes are mapped back toaft_*tool names. - Reload relay config from the sidecar on each request so long-running OpenCode processes stop using stale HTTP/WebSocket settings.
- Reduce fallback OAuth refresh backoff log noise and improve WebSocket relay fallback diagnostics.
- Fix root
bun testand CI workflow test commands.
Thanks to @iceteaSA for the quota manager and TUI sidebar contributions.
- Clarify the
<use_parallel_tool_calls>guidance so agents parallelize only independent tool calls and never invent placeholder task IDs or other values for calls that depend on earlier tool results.
- Add Claude Opus 4.8 support across fast mode, the Pi model catalog, documentation, and cache-usage price estimates.
- Improve
/claude-cache hybridanchor placement for long tool-heavy sessions by moving the rolling anchor to the latest user/tool-result boundary and adding a bridge anchor when Anthropic's 20-block cache lookback would otherwise miss the prior tail anchor. - Add Anthropic's
<use_parallel_tool_calls>system prompt guidance for OpenCode Anthropic chat sessions only, encouraging independent read-only tool calls to be issued in parallel without modifying non-Anthropic model prompts.
- Renew main and fallback OAuth refresh file locks while a refresh is in flight, preventing another OpenCode process from reusing a rotating refresh token if Anthropic's OAuth endpoint is slow to respond.
- Sign only the controlled billing-header CCH placeholder so historical
cch=...;text in prior messages cannot receive the per-request signature and break prompt-cache stability. - Update development and integration dependencies, including OpenCode/Pi SDK packages, Biome, Miniflare, and release workflow pins.
- Add
/claude-routingwith persistedrouting.modeso OpenCode and Pi can switch between the defaultmain-firstrouting andfallback-firstrouting without restarting. - In
fallback-firstmode, usable sidecar fallback accounts are tried before the main account; if no fallback succeeds, the request falls back to the main account.
- Reuse cached fallback-account quota snapshots when transient quota probes are rate limited, so an account with known remaining quota can still be tried instead of falling back to an exhausted main account.
- Reuse fresh fallback-account quota snapshots during explicit quota checks and clear stale quota errors so transient quota-probe
429s do not hide otherwise usable fallback account state.
- Serialize fallback-account OAuth refreshes across OpenCode processes so concurrent refresh attempts cannot reuse and invalidate a rotating refresh token.
- Align Claude OAuth token refresh with the live-tested PR #40 request shape:
https://platform.claude.com/v1/oauth/token, JSON payloads, and anaxios/1.13.6User-Agent. - Honor OAuth
Retry-Afterresponses and skip request-path refresh attempts while main-account backoff is active, reducing repeated refresh failures during Anthropic rate limits.
Thanks to @iceteaSA for the OAuth refresh fixes in this release.
- Add jitter to OpenCode and fallback-account background OAuth refresh timers so concurrent OpenCode processes do not all refresh at the same due timestamp.
- Harden the cross-process main OAuth refresh lock so a process cannot steal a lock while another process is still initializing it, preventing duplicate refresh requests that can consume a rotated refresh token and leave the loser with
invalid_grant. - When a main OAuth refresh is already in progress, wait briefly and re-read OpenCode auth so followers can join the successful token rotation instead of failing immediately.
- Refresh Claude OAuth tokens through
https://api.anthropic.com/v1/oauth/token, matching the live-smoke-tested CLIProxyAPI JSON refresh path, afterplatform.claude.comrepeatedly returned OAuth429during proactive refresh.
- Bundle the OpenCode plugin runtime with Bun so published installs no longer depend on workspace-local source layout.
- Move Pi integration dependencies and imports from the old
@mariozechner/*namespace to@earendil-works/*, including@earendil-works/pi-tui.
- Retry transient Claude OAuth refresh failures in the shared helper while keeping the OpenCode main-account refresh path single-sourced through its existing retry, backoff, and cross-process lock.
- Harden Pi message conversion for empty base64 images, error
tool_resultparts, and tool IDs. - Reduce redundant account-storage reads in fallback routing and quota selection paths.
- Harden relay optimistic-stream error handling and Worker request handling, including deferred KV state writes and a health response.
- Update development dependencies and release workflow actions; release CI now also runs the OpenCode e2e harness before publishing.
Thanks to @iceteaSA for the batch of Pi, fallback, relay, and packaging improvements that went into this release.
- Refresh Claude OAuth tokens earlier by treating
refresh.refreshBeforeExpiryMinutesas a minimum 4-hour window, preventing transient OAuth429backoff from pushing retries past token expiry. - Serialize main OpenCode OAuth refresh across concurrently running OpenCode processes with an atomic filesystem lock, avoiding multi-session refresh races against Anthropic's OAuth endpoint.
- Added
/claude-cachekeepfor hybrid Claude cache mode. It keeps in-memory clones of recently used rewritten requests and sends prewarm-safemax_tokens: 0calls during the configured local time window. - Fixed OAuth refresh backoff after re-login by resetting retry severity when the refresh token rotates.
- Reduced hidden slash-command reply overhead by bounding OpenCode prompt-context lookup to the most recent 100 messages instead of hydrating the full session.
- Initial CortexKit release under
@cortexkit/opencode-anthropic-auth, including multi-account fallback, quota-aware routing, Claude cache controls, Anthropic fast mode toggling, final-body billing signing, and the optional user-owned Cloudflare relay.
- #96
d3d4823Thanks @eliasstepanik! - Re-read auth before token refresh to avoid using a stale refresh token snapshot when token rotation occurs between requests.
- #110
2352c87Thanks @eXamadeus! - Downgrade bun to 1.3.11 to work around a macOS code-signing issue in 1.3.12 that prevents dev-mode testing.
- #106
31b3b99Thanks @eXamadeus! - Bump bun to 1.3.12, ensure we use mise in CI, and lock engines for dev
- #94
522c18dThanks @colus001! - FixCannot find module '.../dist/auth'error when opencode loads the plugin as strict ESM.
- #91
550c408Thanks @bogdan-manole! - fixing the StructuredOutput issue introduced in v1.5.1
-
#88
a90185aThanks @eXamadeus! - Remove system block to user message relocation, remove experimental FF, and align system blocks to match Anthropic -
#87
e3e1be4Thanks @eXamadeus! - Remove OpenCode identity more accurately
- #81
0906d28Thanks @INONONO66! - PascalCase tool names after mcp_ prefix to match Claude Code convention
- #76
d92609cThanks @eXamadeus! - Add inEXPERIMENTAL_KEEP_SYSTEM_PROMPTwhich allows users to keep the sanitized prompt as a system prompt, instead of changing it to a user propmt.
- #74
53b62bbThanks @eXamadeus! - Add in Claude billing header with content consistency hashing from decompiled binary
-
#70
91601b8Thanks @dependabot! - chore(deps-dev): bump @opencode-ai/plugin from 1.3.13 to 1.4.3 -
#71
ce3f9fcThanks @dependabot! - chore(deps-dev): bump lefthook from 2.1.4 to 2.1.5 -
#69
2d9b5bcThanks @dependabot! - chore(deps-dev): bump @biomejs/biome from 2.4.10 to 2.4.11
- #63
69f4754Thanks @eXamadeus! - To bypass Anthropic's scans of the system prompts, move all but the identity marker into a user message
- #61
8dca525Thanks @eXamadeus! - Minor change to identity anchor
- #59
d520d0cThanks @eXamadeus! - Minimize prompt sanitization reach with anchor-based paragraph removal, preserving behavioral guidance that was previously stripped.
- #52
19ea91aThanks @eXamadeus! - Add system prompt sanitization for Max subscription compatibility. Moves system prompt handling from the plugin hook into the request body layer, surgically removing the OpenCode identity section and prepending Claude Code identity. Preserves user-configured instructions from config.json.
- #49
3ad9267Thanks @PaoloC68! - Surface token refresh error body for easier diagnosis; add prepare script for github installs
- #47
c0fbbcfThanks @eXamadeus! - Minor bump to update README in npm with security suggestion
- #42
feec332Thanks @Thesam1798! - feat: support ANTHROPIC_BASE_URL env var for custom API endpoint
-
#39
32240f1Thanks @Thesam1798! - ci: harden workflows for fork safety and concurrency -
#41
386e716Thanks @Thesam1798! - fix: deduplicate concurrent OAuth token refreshes
- #37
97729bcThanks @eXamadeus! - Update copyright year in LICENSE file
-
#31
2ff263fThanks @eXamadeus! - Add in changesets for changeset management and fix type checking -
#33
4523f1bThanks @eXamadeus! - Make sure changeset PRs are run by bot user for CI to trigger -
#34
9c7a9e2Thanks @eXamadeus! - Ensure CI is triggered per release