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.
- package/README.md +201 -84
- package/dist/auth/adapter.d.ts +51 -17
- package/dist/auth/agents/{claude-code-storage.d.ts → claude-storage.d.ts} +13 -5
- package/dist/auth/agents/{claude-code-storage.js → claude-storage.js} +51 -3
- package/dist/auth/agents/{claude-code.js → claude.js} +29 -61
- package/dist/auth/agents/codex-config.js +1 -1
- package/dist/auth/agents/codex.js +23 -12
- package/dist/auth/agents/copilot-storage.js +1 -2
- package/dist/auth/agents/copilot.js +22 -9
- package/dist/auth/agents/gemini-auth-check.d.ts +3 -3
- package/dist/auth/agents/gemini-auth-check.js +32 -45
- package/dist/auth/agents/gemini-install.d.ts +11 -0
- package/dist/auth/agents/gemini-install.js +115 -0
- package/dist/auth/agents/gemini-storage.d.ts +2 -4
- package/dist/auth/agents/gemini-storage.js +4 -12
- package/dist/auth/agents/gemini.js +13 -86
- package/dist/auth/agents/opencode-schema.d.ts +24 -0
- package/dist/auth/agents/opencode-schema.js +42 -0
- package/dist/auth/agents/opencode.d.ts +4 -0
- package/dist/auth/agents/opencode.js +49 -13
- package/dist/auth/registry.d.ts +45 -8
- package/dist/auth/registry.js +91 -8
- package/dist/auth/resolve-config-directory.d.ts +11 -7
- package/dist/auth/resolve-config-directory.js +12 -8
- package/dist/auth/types.d.ts +26 -8
- package/dist/auth/types.js +20 -1
- package/dist/auth/validate-directories.d.ts +25 -0
- package/dist/auth/validate-directories.js +29 -0
- package/dist/cli.js +19 -4
- package/dist/commands/auth.d.ts +5 -11
- package/dist/commands/auth.js +15 -74
- package/dist/commands/install-credentials.d.ts +16 -0
- package/dist/commands/install-credentials.js +77 -0
- package/dist/commands/validate-agent.d.ts +14 -0
- package/dist/commands/validate-agent.js +22 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -4
- /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
|
-
|
|
3
|
+
Unified authentication management for AI coding agents.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
axauth
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
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
|
|
40
|
+
axauth token --agent claude
|
|
52
41
|
|
|
53
42
|
# Export credentials to encrypted file
|
|
54
|
-
axauth export --agent claude
|
|
55
|
-
axauth export --agent claude
|
|
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
|
|
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
|
-
|
|
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
|
|
72
|
-
# claude
|
|
73
|
-
# codex
|
|
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
|
|
74
|
+
axauth list --json | jq -e '.[] | select(.agentId == "claude") | .authenticated'
|
|
87
75
|
|
|
88
|
-
#
|
|
89
|
-
curl -s -H "Authorization: Bearer $(axauth token --agent claude
|
|
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
|
-
##
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
214
|
+
Some agents require specific directory name suffixes:
|
|
129
215
|
|
|
130
|
-
|
|
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
|
-
|
|
133
|
-
# Rule: `axauth` Usage
|
|
224
|
+
## Architecture
|
|
134
225
|
|
|
135
|
-
|
|
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
|
-
|
|
256
|
+
axauth is part of the [a╳point](https://axpoint.dev) ecosystem:
|
|
142
257
|
|
|
143
|
-
|
|
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
|
|
package/dist/auth/adapter.d.ts
CHANGED
|
@@ -16,32 +16,63 @@ interface OperationResult {
|
|
|
16
16
|
/**
|
|
17
17
|
* Options for credential installation.
|
|
18
18
|
*
|
|
19
|
-
* When
|
|
20
|
-
*
|
|
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
|
|
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
|
|
39
|
+
/** Storage type for default location (ignored if configDir/dataDir is set) */
|
|
29
40
|
storage?: StorageType;
|
|
30
|
-
/** Custom
|
|
31
|
-
|
|
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 `
|
|
37
|
-
* Keychain credentials are not affected (keychain is only for
|
|
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
|
-
*
|
|
40
|
-
*
|
|
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
|
|
44
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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, };
|