1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! # entelix-auth-claude-code
//!
//! Claude Code OAuth credential provider for entelix.
//!
//! Reuses the Claude.ai access token the `claude` CLI manages
//! (`~/.claude/.credentials.json` by default), refreshing through
//! the standard OAuth2 `refresh_token` grant against
//! `https://console.anthropic.com/v1/oauth/token` when the access
//! token approaches expiry.
//!
//! ## Why
//!
//! Operators with a Claude.ai pro / team subscription get to drive
//! entelix without minting a separate Anthropic API key — the same
//! credential their `claude` CLI uses flows straight into the
//! `entelix_core::auth::CredentialProvider` chain. Refresh-token
//! rotation is handled automatically and storage stays compatible
//! with the upstream CLI, so both tools share state.
//!
//! ## Layout
//!
//! ```text
//! ClaudeCodeOAuthProvider — impl entelix_core::auth::CredentialProvider
//! └─ CredentialStore trait — operator-supplied backend
//! └─ FileCredentialStore — default; reads / writes the on-disk JSON
//! └─ ClaudeCodeOAuthConfig — token URL / client id / refresh timeout
//! └─ refresh_access_token — RFC 6749 §6 grant
//! ```
//!
//! [`CredentialStore`] is a trait so vault / Keychain / Secret
//! Service backends plug in by implementing it; the default ships
//! only the file backend so the dependency footprint stays minimal.
//!
//! ## Beta capability gate
//!
//! Claude Code's OAuth tokens require the `claude-code-20250219`
//! anthropic-beta header. The provider deliberately *does not*
//! inject the header — credentials and codec ext stay independent
//! (single responsibility). Operators wire it through
//! [`entelix_core::ir::AnthropicExt::with_betas`] using
//! [`CLAUDE_CODE_BETA`]:
//!
//! ```ignore
//! use entelix_auth_claude_code::{
//! CLAUDE_CODE_BETA, ClaudeCodeOAuthProvider, FileCredentialStore,
//! };
//! use entelix_core::ir::{AnthropicExt, ProviderExtensions};
//!
//! let store = FileCredentialStore::with_path(
//! FileCredentialStore::default_claude_path()?,
//! );
//! let provider = ClaudeCodeOAuthProvider::new(store);
//! // Apply the matching beta capability on every outgoing request:
//! let extensions = ProviderExtensions::default()
//! .with_anthropic(AnthropicExt::default().with_betas([CLAUDE_CODE_BETA]));
//! ```
//!
//! ## Store hygiene
//!
//! [`FileCredentialStore`] reads and writes the credential file on a
//! `tokio::task::spawn_blocking` worker so the async runtime never
//! stalls on disk IO. Operators that need an in-memory backend
//! (env-var-driven, vault) implement [`CredentialStore`] directly
//! without touching the file path.
// Doc-prose lints fire on legitimate proper nouns / acronyms (Claude
// Code, OAuth2, RFC 6749, …); the redundant_pub_crate lint disagrees
// with the workspace `unreachable_pub` rule for items inside private
// modules — same exemption pattern as `entelix-tools`.
pub use ;
pub use ;
pub use ;
pub use ClaudeCodeOAuthProvider;
pub use ;