axauth 1.0.0 → 1.2.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.
Files changed (39) hide show
  1. package/README.md +201 -84
  2. package/dist/auth/adapter.d.ts +51 -17
  3. package/dist/auth/agents/{claude-code-storage.d.ts → claude-storage.d.ts} +13 -5
  4. package/dist/auth/agents/{claude-code-storage.js → claude-storage.js} +51 -3
  5. package/dist/auth/agents/{claude-code.js → claude.js} +29 -61
  6. package/dist/auth/agents/codex-config.js +1 -1
  7. package/dist/auth/agents/codex.js +23 -12
  8. package/dist/auth/agents/copilot-storage.js +1 -2
  9. package/dist/auth/agents/copilot.js +22 -9
  10. package/dist/auth/agents/gemini-auth-check.d.ts +3 -3
  11. package/dist/auth/agents/gemini-auth-check.js +32 -45
  12. package/dist/auth/agents/gemini-install.d.ts +11 -0
  13. package/dist/auth/agents/gemini-install.js +115 -0
  14. package/dist/auth/agents/gemini-storage.d.ts +2 -4
  15. package/dist/auth/agents/gemini-storage.js +4 -12
  16. package/dist/auth/agents/gemini.js +13 -86
  17. package/dist/auth/agents/opencode-schema.d.ts +24 -0
  18. package/dist/auth/agents/opencode-schema.js +42 -0
  19. package/dist/auth/agents/opencode.d.ts +4 -0
  20. package/dist/auth/agents/opencode.js +49 -13
  21. package/dist/auth/registry.d.ts +45 -8
  22. package/dist/auth/registry.js +91 -8
  23. package/dist/auth/resolve-config-directory.d.ts +11 -7
  24. package/dist/auth/resolve-config-directory.js +12 -8
  25. package/dist/auth/types.d.ts +26 -8
  26. package/dist/auth/types.js +20 -1
  27. package/dist/auth/validate-directories.d.ts +25 -0
  28. package/dist/auth/validate-directories.js +29 -0
  29. package/dist/cli.js +19 -4
  30. package/dist/commands/auth.d.ts +5 -11
  31. package/dist/commands/auth.js +15 -74
  32. package/dist/commands/install-credentials.d.ts +16 -0
  33. package/dist/commands/install-credentials.js +77 -0
  34. package/dist/commands/validate-agent.d.ts +14 -0
  35. package/dist/commands/validate-agent.js +22 -0
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.js +1 -1
  38. package/package.json +5 -4
  39. /package/dist/auth/agents/{claude-code.d.ts → claude.d.ts} +0 -0
package/README.md CHANGED
@@ -1,46 +1,35 @@
1
1
  # axauth
2
2
 
3
- Authentication management library and CLI for AI coding agents.
3
+ Unified authentication management for AI coding agents.
4
4
 
5
5
  ## Overview
6
6
 
7
- axauth manages credentials for AI coding agents. It can be used:
7
+ axauth provides a consistent interface for managing credentials across multiple AI coding agent CLIs. It abstracts away the differences between agent-specific credential storage mechanisms (macOS Keychain, file-based storage, environment variables) and provides:
8
8
 
9
- 1. **As a library** - imported to check auth status, extract tokens, and manage credentials programmatically
10
- 2. **As a CLI** - standalone tool for managing agent credentials
9
+ - **Auth status detection** - Check which agents are authenticated and via which method
10
+ - **Credential extraction** - Extract tokens for API calls or export/import workflows
11
+ - **Portable credential export** - Encrypted credential files for CI/CD and backup
12
+ - **Multi-storage support** - Keychain (macOS), file storage, and environment variables
11
13
 
12
14
  ## Supported Agents
13
15
 
14
- - **claude-code** - Claude Code (Anthropic)
15
- - **codex** - Codex CLI (OpenAI)
16
- - **gemini** - Gemini CLI (Google)
17
- - **opencode** - OpenCode
16
+ | Agent | CLI | Provider | Auth Methods |
17
+ | ----------- | ---------- | --------- | ------------------------------------------ |
18
+ | Claude Code | `claude` | Anthropic | OAuth (keychain/file), `ANTHROPIC_API_KEY` |
19
+ | Codex CLI | `codex` | OpenAI | ChatGPT OAuth, `OPENAI_API_KEY` |
20
+ | Gemini CLI | `gemini` | Google | OAuth, `GEMINI_API_KEY` |
21
+ | OpenCode | `opencode` | Sst | Multi-provider OAuth |
22
+ | Copilot CLI | `copilot` | GitHub | OAuth, `GH_TOKEN`/`GITHUB_TOKEN` |
18
23
 
19
- ## Library API
20
-
21
- ```typescript
22
- import { checkAuth, getAgentAccessToken, extractCredentials } from "axauth";
23
-
24
- // Check auth status for an agent
25
- const status = checkAuth("claude-code");
26
- if (status.authenticated) {
27
- console.log(`Authenticated via ${status.method}`);
28
- }
24
+ ## Installation
29
25
 
30
- // Get access token for API calls
31
- const token = getAgentAccessToken("claude-code");
32
- if (token) {
33
- // Use token for API calls
34
- }
35
-
36
- // Extract full credentials for export
37
- const creds = extractCredentials("claude-code");
38
- if (creds) {
39
- // creds.accessToken, creds.refreshToken, etc.
40
- }
26
+ ```bash
27
+ npm install axauth
28
+ # or
29
+ pnpm add axauth
41
30
  ```
42
31
 
43
- ## CLI Commands
32
+ ## CLI Usage
44
33
 
45
34
  ```bash
46
35
  # List agents and their auth status
@@ -48,29 +37,31 @@ axauth list
48
37
  axauth list --json
49
38
 
50
39
  # Get access token for an agent (outputs raw token for piping)
51
- axauth token --agent claude-code
40
+ axauth token --agent claude
52
41
 
53
42
  # Export credentials to encrypted file
54
- axauth export --agent claude-code --output creds.json
55
- axauth export --agent claude-code --output creds.json --no-password
56
-
57
- # Remove credentials (agent will prompt for login)
58
- axauth remove-credentials --agent claude-code
43
+ axauth export --agent claude --output creds.json
44
+ axauth export --agent claude --output creds.json --no-password
59
45
 
60
46
  # Install credentials from exported file
61
- axauth install-credentials --agent claude-code --input creds.json
47
+ axauth install-credentials --agent claude --input creds.json
48
+ axauth install-credentials --agent claude --input creds.json --config-dir /tmp/config
49
+
50
+ # Remove credentials (agent will prompt for login on next use)
51
+ axauth remove-credentials --agent claude
52
+ axauth remove-credentials --agent claude --config-dir /tmp/config
62
53
  ```
63
54
 
64
- ## Pipeline Examples
55
+ ### Pipeline Examples
65
56
 
66
57
  The CLI outputs TSV format for easy processing with standard Unix tools:
67
58
 
68
59
  ```bash
69
60
  # List all agents and their auth status
70
61
  axauth list
71
- # AGENT STATUS METHOD
72
- # claude-code authenticated OAuth (max)
73
- # codex authenticated ChatGPT OAuth
62
+ # AGENT STATUS METHOD
63
+ # claude authenticated OAuth (max)
64
+ # codex authenticated ChatGPT OAuth
74
65
  # ...
75
66
 
76
67
  # Filter to show only authenticated agents
@@ -79,68 +70,194 @@ axauth list | tail -n +2 | awk -F'\t' '$2 == "authenticated"'
79
70
  # Count agents by status
80
71
  axauth list | tail -n +2 | cut -f2 | sort | uniq -c
81
72
 
82
- # Extract agent names as a list
83
- axauth list | tail -n +2 | cut -f1
84
-
85
73
  # Check if a specific agent is authenticated
86
- axauth list --json | jq -e '.[] | select(.agentId == "claude-code") | .authenticated'
74
+ axauth list --json | jq -e '.[] | select(.agentId == "claude") | .authenticated'
87
75
 
88
- # Check Claude Code usage via OAuth endpoint
89
- curl -s -H "Authorization: Bearer $(axauth token --agent claude-code)" \
76
+ # Use token with curl
77
+ curl -s -H "Authorization: Bearer $(axauth token --agent claude)" \
90
78
  -H "anthropic-beta: oauth-2025-04-20" \
91
79
  https://api.anthropic.com/api/oauth/usage | jq .
92
80
  ```
93
81
 
94
- ## Module Structure
82
+ ## Library API
95
83
 
84
+ ```typescript
85
+ import {
86
+ // Core operations
87
+ checkAuth, // Check single agent auth status
88
+ checkAllAuth, // Check all agents' auth status
89
+ getAgentAccessToken, // Get access token for an agent
90
+ extractRawCredentials, // Extract full credentials for export
91
+ installCredentials, // Install credentials to storage
92
+ removeCredentials, // Remove credentials from storage
93
+
94
+ // Credential utilities
95
+ getAccessToken, // Extract token from credential object
96
+ credentialsToEnvironment, // Convert credentials to env vars
97
+ getCredentialsEnvironmentVariableName, // Get AX_*_CREDENTIALS var name
98
+ installCredentialsFromEnvironmentVariable, // Install from env var (CI/CD)
99
+
100
+ // Adapter access
101
+ getAdapter, // Get adapter for an agent
102
+ getAllAdapters, // Get all adapters
103
+ getCapabilities, // Check adapter capabilities
104
+ } from "axauth";
105
+
106
+ // Types
107
+ import type {
108
+ AgentCli, // "claude" | "codex" | "gemini" | "opencode" | "copilot"
109
+ AuthStatus, // { agentId, authenticated, method?, details? }
110
+ Credentials, // { agent, type, data }
111
+ AuthAdapter, // Adapter interface
112
+ AdapterCapabilities, // { keychain, file, environment, installApiKey }
113
+ } from "axauth";
96
114
  ```
97
- src/
98
- ├── types.ts # AgentId type definition
99
- ├── crypto.ts # AES-256-GCM encryption for credentials
100
- ├── cli.ts # CLI entry point
101
- ├── commands/
102
- │ └── auth.ts # CLI command handlers
103
- └── auth/
104
- ├── check-auth.ts # Auth status detection
105
- ├── extract-credentials.ts # Credential extraction
106
- ├── get-access-token.ts # Token retrieval
107
- ├── install-credentials.ts # Credential installation
108
- ├── remove-credentials.ts # Credential removal
109
- ├── keychain.ts # macOS Keychain utilities
110
- ├── file-storage.ts # File I/O utilities
111
- ├── types.ts # Auth types
112
- └── agents/ # Agent-specific implementations
113
- ├── claude-code.ts
114
- ├── codex.ts
115
- ├── gemini.ts
116
- └── opencode.ts
115
+
116
+ ### Examples
117
+
118
+ ```typescript
119
+ import { checkAuth, getAgentAccessToken, getCapabilities } from "axauth";
120
+
121
+ // Check auth status for an agent
122
+ const status = checkAuth("claude");
123
+ if (status.authenticated) {
124
+ console.log(`Authenticated via ${status.method}`);
125
+ }
126
+
127
+ // Get access token for API calls
128
+ const token = getAgentAccessToken("claude");
129
+ if (token) {
130
+ // Use token for API calls
131
+ }
132
+
133
+ // Check adapter capabilities
134
+ const caps = getCapabilities("gemini");
135
+ if (!caps.keychain) {
136
+ console.log("Gemini requires file storage on this platform");
137
+ }
138
+ ```
139
+
140
+ ### Adapter Pattern
141
+
142
+ Each agent implements the `AuthAdapter` interface, hiding storage complexity:
143
+
144
+ ```typescript
145
+ import { getAdapter } from "axauth";
146
+
147
+ const adapter = getAdapter("claude");
148
+
149
+ // All adapters have the same interface
150
+ const status = adapter.checkAuth();
151
+ const creds = adapter.extractRawCredentials();
152
+ const token = adapter.getAccessToken(creds);
153
+ const envVars = adapter.credentialsToEnvironment(creds);
154
+
155
+ // Check what the adapter supports
156
+ console.log(adapter.capabilities);
157
+ // { keychain: true, file: true, environment: true, installApiKey: false }
158
+ ```
159
+
160
+ ## Adapter Capabilities
161
+
162
+ Each agent adapter declares its storage capabilities:
163
+
164
+ | Agent | Keychain | File | Environment | Install API Key |
165
+ | -------- | :------: | :--: | :---------: | :-------------: |
166
+ | claude | macOS | Yes | Yes | No (env-only) |
167
+ | codex | macOS | Yes | Yes | No (env-only) |
168
+ | gemini | macOS | Yes | Yes | No (env-only) |
169
+ | opencode | No | Yes | Yes | No |
170
+ | copilot | macOS | Yes | Yes | No (env-only) |
171
+
172
+ **Notes:**
173
+
174
+ - **Keychain**: macOS Keychain support (not available on Linux/Windows)
175
+ - **File**: File-based credential storage
176
+ - **Environment**: Can read credentials from environment variables
177
+ - **Install API Key**: Whether API keys can be installed (vs. read from env only)
178
+
179
+ ## Credential Export Format
180
+
181
+ Exported credentials are encrypted with AES-256-GCM:
182
+
183
+ ```json
184
+ {
185
+ "version": 1,
186
+ "agent": "claude",
187
+ "ciphertext": "<base64>",
188
+ "salt": "<base64>",
189
+ "iv": "<base64>",
190
+ "tag": "<base64>"
191
+ }
117
192
  ```
118
193
 
119
- ## Authentication Methods
194
+ - Key derivation: PBKDF2 with SHA-256, 100,000 iterations
195
+ - Use `--no-password` for CI/CD (uses a default password)
196
+ - Files are written with `0o600` permissions
197
+
198
+ ## Environment Variables
199
+
200
+ For CI/CD workflows, credentials can be passed via environment variables:
201
+
202
+ | Agent | Credential Env Var |
203
+ | -------- | ------------------------- |
204
+ | claude | `AX_CLAUDE_CREDENTIALS` |
205
+ | codex | `AX_CODEX_CREDENTIALS` |
206
+ | gemini | `AX_GEMINI_CREDENTIALS` |
207
+ | copilot | `AX_COPILOT_CREDENTIALS` |
208
+ | opencode | `AX_OPENCODE_CREDENTIALS` |
209
+
210
+ Use `installCredentialsFromEnvironmentVariable()` to install credentials from these variables programmatically.
120
211
 
121
- | Agent | Methods |
122
- | ----------- | ------------------------------------------ |
123
- | claude-code | OAuth (keychain/file) or ANTHROPIC_API_KEY |
124
- | codex | ChatGPT OAuth or OPENAI_API_KEY |
125
- | gemini | OAuth or GEMINI_API_KEY |
126
- | opencode | Multi-provider OAuth |
212
+ ## Config Directory Requirements
127
213
 
128
- ## Agent Rule
214
+ Some agents require specific directory name suffixes:
129
215
 
130
- Add to your `CLAUDE.md` or `AGENTS.md`:
216
+ | Agent | Directory Requirement | Example |
217
+ | -------- | ------------------------ | -------------------- |
218
+ | claude | Any name | `/tmp/my-config` |
219
+ | codex | Any name | `/tmp/my-config` |
220
+ | gemini | Must end with `.gemini` | `/tmp/home/.gemini` |
221
+ | copilot | Must end with `.copilot` | `/tmp/home/.copilot` |
222
+ | opencode | Must end with `opencode` | `/tmp/data/opencode` |
131
223
 
132
- ```markdown
133
- # Rule: `axauth` Usage
224
+ ## Architecture
134
225
 
135
- Run `npx -y axauth --help` to learn available options.
226
+ axauth follows the adapter pattern with a functional core:
136
227
 
137
- Use `axauth` to manage AI agent credentials. Check auth status with `axauth list`,
138
- get tokens with `axauth token`, and export/import credentials for CI/CD workflows.
139
228
  ```
229
+ src/
230
+ ├── index.ts # Public API exports
231
+ ├── cli.ts # CLI entry point
232
+ ├── crypto.ts # AES-256-GCM encryption
233
+ ├── commands/
234
+ │ └── auth.ts # CLI command handlers
235
+ └── auth/
236
+ ├── adapter.ts # AuthAdapter interface
237
+ ├── types.ts # AuthStatus, Credentials types
238
+ ├── registry.ts # Adapter registry and unified operations
239
+ └── agents/ # Agent-specific adapters
240
+ ├── claude-code.ts
241
+ ├── claude-code-storage.ts
242
+ ├── codex.ts
243
+ ├── codex-storage.ts
244
+ ├── codex-config.ts
245
+ ├── gemini.ts
246
+ ├── gemini-storage.ts
247
+ ├── gemini-auth-check.ts
248
+ ├── copilot.ts
249
+ ├── copilot-storage.ts
250
+ ├── copilot-auth-check.ts
251
+ └── opencode.ts
252
+ ```
253
+
254
+ ## Related Packages
140
255
 
141
- ## Development Status
256
+ axauth is part of the [a╳point](https://axpoint.dev) ecosystem:
142
257
 
143
- 🚧 **Work in Progress**
258
+ - **axshared** - Shared types and agent metadata
259
+ - **axconfig** - Permission and configuration management
260
+ - **axrun** - Agent execution and output normalization
144
261
 
145
262
  ## License
146
263
 
@@ -16,32 +16,63 @@ interface OperationResult {
16
16
  /**
17
17
  * Options for credential installation.
18
18
  *
19
- * When `path` is provided, credentials are always written as a file to that
20
- * path (keychain is only for default location). The `storage` option is ignored.
19
+ * When custom directories are provided, credentials are always written as files
20
+ * (keychain is only for default location). The `storage` option is ignored.
21
21
  *
22
- * When `path` is not provided, `storage` controls where credentials go:
22
+ * When no directories are provided, `storage` controls where credentials go:
23
23
  * - `"keychain"`: Store in macOS Keychain (if supported)
24
24
  * - `"file"`: Store in agent's default file location
25
25
  * - `undefined`: Use the `_source` marker in credentials, or default to file
26
+ *
27
+ * **Agents without separation** (Claude, Codex, Gemini, Copilot):
28
+ * - Config and data are stored in the same directory
29
+ * - `configDir` and `dataDir` are interchangeable (either works)
30
+ * - Providing different values for both will result in an error
31
+ *
32
+ * **Agents with separation** (OpenCode):
33
+ * - Config and data are stored in separate directories
34
+ * - `dataDir` controls where credentials go; `configDir` is for settings
35
+ * - If only `configDir` provided, credentials use default data location
36
+ * - If only `dataDir` provided, config uses default location
26
37
  */
27
38
  interface InstallOptions {
28
- /** Storage type for default location (ignored if path is set) */
39
+ /** Storage type for default location (ignored if configDir/dataDir is set) */
29
40
  storage?: StorageType;
30
- /** Custom file path (forces file storage, keychain not available) */
31
- path?: string;
41
+ /** Custom config directory for settings/preferences */
42
+ configDir?: string;
43
+ /** Custom data directory for credentials */
44
+ dataDir?: string;
32
45
  }
33
46
  /**
34
47
  * Options for credential removal.
35
48
  *
36
- * When `path` is provided, only the file at that path is removed.
37
- * Keychain credentials are not affected (keychain is only for default location).
49
+ * When `dataDir` is provided, only the credentials file in that directory
50
+ * is removed. Keychain credentials are not affected (keychain is only for
51
+ * default location).
38
52
  *
39
- * When `path` is not provided, credentials are removed from all default
40
- * locations (keychain and/or default file path).
53
+ * **Agents without separation** (Claude, Codex, Gemini, Copilot):
54
+ * - `configDir` and `dataDir` are interchangeable
55
+ * - Either option specifies where to remove credentials from
56
+ *
57
+ * **Agents with separation** (OpenCode):
58
+ * - `dataDir` specifies where to remove credentials from
59
+ * - If only `configDir` provided, credentials are removed from default location
41
60
  */
42
61
  interface RemoveOptions {
43
- /** Custom file path to remove (only removes this file, not keychain) */
44
- path?: string;
62
+ /** Custom config directory for settings/preferences */
63
+ configDir?: string;
64
+ /** Custom data directory for credentials */
65
+ dataDir?: string;
66
+ }
67
+ /**
68
+ * Options for token extraction.
69
+ *
70
+ * Some agents (like opencode) support multiple providers. Use the `provider`
71
+ * option to specify which provider's token to extract.
72
+ */
73
+ interface TokenOptions {
74
+ /** Provider ID for multi-provider agents (e.g., "anthropic", "openai") */
75
+ provider?: string;
45
76
  }
46
77
  /** Capabilities that an adapter supports */
47
78
  interface AdapterCapabilities {
@@ -95,10 +126,10 @@ interface AuthAdapter {
95
126
  /**
96
127
  * Remove credentials from storage.
97
128
  *
98
- * When `options.path` is provided, only the file at that path is removed.
99
- * Keychain credentials are not affected.
129
+ * When `options.configDir` is provided, only the credentials file in that
130
+ * directory is removed. Keychain credentials are not affected.
100
131
  *
101
- * When `options.path` is not provided, credentials are removed from all
132
+ * When `options.configDir` is not provided, credentials are removed from all
102
133
  * default locations (keychain and/or default file path).
103
134
  */
104
135
  removeCredentials(options?: RemoveOptions): OperationResult;
@@ -107,8 +138,11 @@ interface AuthAdapter {
107
138
  *
108
139
  * Returns the primary access token (OAuth token or API key) from
109
140
  * the credential data. Returns undefined if no token found.
141
+ *
142
+ * For multi-provider agents (like opencode), use `options.provider`
143
+ * to specify which provider's token to extract.
110
144
  */
111
- getAccessToken(creds: Credentials): string | undefined;
145
+ getAccessToken(creds: Credentials, options?: TokenOptions): string | undefined;
112
146
  /**
113
147
  * Convert credentials to environment variables.
114
148
  *
@@ -118,4 +152,4 @@ interface AuthAdapter {
118
152
  */
119
153
  credentialsToEnvironment(creds: Credentials): Record<string, string>;
120
154
  }
121
- export type { AdapterCapabilities, AuthAdapter, InstallOptions, OperationResult, RemoveOptions, };
155
+ export type { AdapterCapabilities, AuthAdapter, InstallOptions, OperationResult, RemoveOptions, TokenOptions, };
@@ -3,10 +3,6 @@
3
3
  */
4
4
  /** Get default credentials file path */
5
5
  declare function getDefaultCredsFilePath(): string;
6
- /** Load OAuth credentials from keychain */
7
- declare function loadKeychainCreds(): Record<string, unknown> | undefined;
8
- /** Load OAuth credentials from file */
9
- declare function loadFileCreds(): Record<string, unknown> | undefined;
10
6
  /** Save credentials to keychain */
11
7
  declare function saveKeychainCreds(oauthData: Record<string, unknown>): boolean;
12
8
  /** Save credentials to file */
@@ -15,4 +11,16 @@ declare function saveFileCreds(oauthData: Record<string, unknown>, filePath: str
15
11
  declare function deleteKeychainCreds(): boolean;
16
12
  /** Delete credentials from file */
17
13
  declare function deleteFileCreds(filePath?: string): boolean;
18
- export { deleteFileCreds, deleteKeychainCreds, getDefaultCredsFilePath, loadFileCreds, loadKeychainCreds, saveFileCreds, saveKeychainCreds, };
14
+ declare const AGENT_ID: "claude";
15
+ /** Check if Claude is authenticated and return status */
16
+ declare function checkAuth(): {
17
+ authenticated: boolean;
18
+ method?: string;
19
+ details?: Record<string, unknown>;
20
+ };
21
+ /** Extract raw credentials from available sources */
22
+ declare function extractRawCredentials(): {
23
+ type: "oauth" | "api-key";
24
+ data: Record<string, unknown>;
25
+ } | undefined;
26
+ export { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, };
@@ -4,7 +4,6 @@
4
4
  import { existsSync, readFileSync } from "node:fs";
5
5
  import { userInfo } from "node:os";
6
6
  import path from "node:path";
7
- import { claudeCodeConfigReader } from "axconfig";
8
7
  import { deleteFile, loadJsonFile, saveJsonFile } from "../file-storage.js";
9
8
  import { getResolvedConfigDirectory } from "../resolve-config-directory.js";
10
9
  import { deleteFromKeychain, loadFromKeychain, saveToKeychain, } from "../keychain.js";
@@ -15,7 +14,7 @@ function getUsername() {
15
14
  }
16
15
  /** Get default credentials file path */
17
16
  function getDefaultCredsFilePath() {
18
- return path.join(getResolvedConfigDirectory(claudeCodeConfigReader), ".credentials.json");
17
+ return path.join(getResolvedConfigDirectory("claude"), ".credentials.json");
19
18
  }
20
19
  /** Load OAuth credentials from keychain */
21
20
  function loadKeychainCreds() {
@@ -63,4 +62,53 @@ function deleteKeychainCreds() {
63
62
  function deleteFileCreds(filePath) {
64
63
  return deleteFile(filePath ?? getDefaultCredsFilePath());
65
64
  }
66
- export { deleteFileCreds, deleteKeychainCreds, getDefaultCredsFilePath, loadFileCreds, loadKeychainCreds, saveFileCreds, saveKeychainCreds, };
65
+ const AGENT_ID = "claude";
66
+ /** Check if Claude is authenticated and return status */
67
+ function checkAuth() {
68
+ if (process.env.CLAUDE_CODE_OAUTH_TOKEN) {
69
+ return { authenticated: true, method: "OAuth (env)" };
70
+ }
71
+ const keychainCreds = loadKeychainCreds();
72
+ if (keychainCreds) {
73
+ const subType = keychainCreds.subscriptionType;
74
+ return { authenticated: true, method: `OAuth (${subType ?? "keychain"})` };
75
+ }
76
+ if (loadFileCreds()) {
77
+ return { authenticated: true, method: "OAuth (file)" };
78
+ }
79
+ if (process.env.ANTHROPIC_API_KEY) {
80
+ return { authenticated: true, method: "API key" };
81
+ }
82
+ return { authenticated: false };
83
+ }
84
+ /** Extract raw credentials from available sources */
85
+ function extractRawCredentials() {
86
+ if (process.env.CLAUDE_CODE_OAUTH_TOKEN) {
87
+ return {
88
+ type: "oauth",
89
+ data: { accessToken: process.env.CLAUDE_CODE_OAUTH_TOKEN },
90
+ };
91
+ }
92
+ const keychainCreds = loadKeychainCreds();
93
+ if (keychainCreds) {
94
+ return {
95
+ type: "oauth",
96
+ data: { ...keychainCreds, _source: "keychain" },
97
+ };
98
+ }
99
+ const fileCreds = loadFileCreds();
100
+ if (fileCreds) {
101
+ return {
102
+ type: "oauth",
103
+ data: { ...fileCreds, _source: "file" },
104
+ };
105
+ }
106
+ if (process.env.ANTHROPIC_API_KEY) {
107
+ return {
108
+ type: "api-key",
109
+ data: { apiKey: process.env.ANTHROPIC_API_KEY },
110
+ };
111
+ }
112
+ return undefined;
113
+ }
114
+ export { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, };