@justjoshn/pi-anthropic-oauth0.1.8
Use a Claude Pro or Max subscription in Pi. Requests identify as Provider CLI.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-anthropic-oauth
Use a Claude subscription in Pi through its native provider, login, credential storage, and Anthropic streaming mechanisms.
The package registers claude-subscription. Existing credentials and saved model selections keep that provider ID. After login, Pi's auth.json is the only store this package uses for requests and refresh.
Pi 1.5.0 compatibility
Pi 1.5.0 is the upgrade target. Its public extension API retains provider registration, native authentication, request hooks, virtual models, and tool-result usage. Those contracts do not establish complete Claude Code parity or remove the request-identity and tool-name adapters. The checked-in Pi 1.4.0 receipts remain historical runtime evidence, not Pi 1.5.0 results. See the native-gap audit.
Sign in through Pi
From this directory, start Pi:
pi -e .
Run /login, choose Claude subscription, then Claude subscription (Provider CLI). Login uses this package's Pi-native OAuth client. Choose Paste code (default), Browser callback, or Import from Claude Code.
- Paste code. Opens Claude Code's copy-code authorize URL (
https://claude.com/cai/oauth/authorizewith the measured scope set, includinguser:plugins), then you paste the code Anthropic shows. - Browser callback. Binds an ephemeral
http://localhost:{port}/callbackand uses that sameredirect_urion authorize and token exchange. - Import from Claude Code. Reads an existing Claude Code session from the macOS Keychain item
Claude Code-credentials(account is yourUSER) when present, otherwise from~/.claude/.credentials.json(orCLAUDE_CONFIG_DIR/CLAUDE_SECURESTORAGE_CONFIG_DIR). It mapsclaudeAiOauthinto a Pi oauth credential and writes only Pi's store. It never runs theclaudebinary and never writes Claude's credential files.
Paste code and browser callback both exchange with an independent OAuth state and refresh with Claude's measured refresh scopes. Select a claude-subscription model with /model.
To install the package, run pi install npm:@justjoshn/pi-anthropic-oauth, or pi install with this directory's path.
Use a setup token
Generate a subscription token with claude setup-token. Supply it through CLAUDE_CODE_OAUTH_TOKEN using your shell's secret-input mechanism. Do not put the token in scripts, project settings, or shell history.
Start Pi with the provider selected:
pi -e . --provider claude-subscription --model claude-sonnet-4-6
When both ANTHROPIC_AUTH_TOKEN and CLAUDE_CODE_OAUTH_TOKEN are set, the auth token wins, matching Claude Code 2.1.316 print mode and auth status. The provider does not read ANTHROPIC_OAUTH_TOKEN. Claude Code's CLI does not consult that variable either. API keys are rejected on these paths. Ambient tokens are not copied into Pi's credential store and cannot refresh themselves.
Pi's stored credential takes precedence over ambient tokens. Use Pi's /logout if you want to stop using the stored credential. A failed refresh retains that credential rather than silently switching accounts.
Override request headers
Use Pi's models.json for explicit header overrides. For example:
{
"providers": {
"claude-subscription": {
"headers": { "user-agent": "claude-cli/2.1.316 (external, sdk-cli)" }
}
}
}
The default identity matches the pinned Claude Code 2.1.316 request for Reply LOCAL_OK.. Additional synthetic text captures agree with the existing billing rule at tested length boundaries and for Unicode; this does not establish its private implementation or arbitrary-input parity. The target derives the billing fingerprint from the first user text that is not duck-typed isMeta. Header overrides do not change the pinned version used in that fingerprint. Ambient auth is oauth-only (ANTHROPIC_AUTH_TOKEN then CLAUDE_CODE_OAUTH_TOKEN). API keys are rejected.
Pi still controls thinking, output limits, tool execution, retries, compaction, model selection, and usage accounting. The package does not replace Pi's prompt or Bash-output policy.
The package reads Pi's projected context and the exact outgoing payload to keep subscription requests under the endpoint's model limit. It compacts at the prompt boundary when Claude Code's accounting says the request would reach Claude Code's compact threshold, and it fits a request that would otherwise exceed the blocking threshold without changing the session history. Pi still owns summarization, persistence, and the session store.
Read the parity matrix for verified behavior, deliberate differences, native API gaps, and live-authentication limitations. This package does not claim complete Claude Code feature parity.
Tool-name limits
OAuth tool renaming can fold names such as Task and task. The first declaration wins, so rename one tool if both are required. Pi supports inline tool changes on capable models. The Pi 1.4.0 receipts below verify the collision workaround on that host. When a transcript has colliding identities, the package preserves the upstream request-local compatibility adjustment that selects Pi's current-tool path. Other transcripts keep native inline tool changes. This trades inline cache reuse for consistent declarations and reply dispatch.
Verify the integration
These checks require a source checkout. The installed package includes the parity matrix, but not tests or verification scripts.
From the repository root, install the declared dependencies:
bun install --frozen-lockfile
From this directory, run the checks:
bun run test
bun run typecheck
bun run test:coverage
bunx vitest run --sequence.shuffle
bun run prove
From the repository root, make verify-oauth runs typecheck, coverage, and bun run prove for this package. The prove scripts use the pinned @earendil-works/pi-coding-agent CLI bundle and local HTTP peers. They stay offline and do not need a separate pi install.
The tests use native Pi providers, authentication, and streams against local HTTP peers. prove-request-paths.ts verifies normal prompts, compaction, virtual routing, the default identity header on every path, the Claude session header, and models.json header overrides. prove-context-guard.ts reproduces the cross-provider context-limit wedge with --expect red on the parent commit and verifies that the guard keeps every request under the window with --expect green. prove-native.ts verifies print, JSON, RPC, ambient authentication, session correlation, fork, reload, session replacement, tool execution, native Bash output, and cancellation.
These probes use disposable Pi directories and synthetic tokens. They do not contact Anthropic for inference or inspect your credentials. Set PI_OAUTH_CLI_PATH to an installed Pi's dist/bundle/cli.js to repeat them against that host. They otherwise use the package's pinned Pi test dependency. The 1.4.0 receipts and the historical 1.0.0, 1.0.1, and 1.1.0 receipts live under docs/verification/.
A live Anthropic authorize→exchange probe exists as bun run live:exchange. It stays off in CI. It runs only when parity/oauth-rea-2026-10-31/claude/gates.md marks ANTH-LIVE-021 as approved and PI_ANTHROPIC_OAUTH_LIVE_EXCHANGE=1. A successful run writes a redacted receipt under parity/oauth-rea-2026-10-31/claude/receipts/.
Capture the installed Claude Code reference with Python 3:
python3 scripts/capture-claude.py
The capture runs Claude Code with an isolated home, safe mode, no tools, no session persistence, a synthetic OAuth token, and a local Messages endpoint. These settings alone do not enforce network or credential isolation. Historical evidence captures for older fixtures additionally used an OS sandbox. The 2.1.312 capture used the isolated home and loopback gateway without that sandbox. The historical 2.1.288, 2.1.296, 2.1.311, and 2.1.312 fixtures are preserved. The current pin lives in test/fixtures/claude-code-2.1.316.json. No auth headers, account identifiers, complete prompts, or credential contents appear in the output. CLAUDE_BIN can select a different Claude executable.
When refreshing the identity, recapture the reference and update src/identity.ts and its literal regression vectors together. Do not import Claude Code internals or execute Claude Code from the extension factory.
From the repository root, run the packaging and style checks:
bunx biome ci extensions/pi-anthropic-oauth --error-on-warnings --max-diagnostics=none
bun run check:tests
node scripts/check-pi-mechanisms.mjs