@cleocode/adapters 2026.5.74 → 2026.5.75
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/dist/index.js +36 -27
- package/dist/index.js.map +3 -3
- package/dist/providers/claude-sdk/spawn.d.ts.map +1 -1
- package/dist/providers/shared/credentials.d.ts +58 -0
- package/dist/providers/shared/credentials.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/providers/claude-sdk/spawn.ts +4 -49
- package/src/providers/shared/credentials.ts +101 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-sdk/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-sdk/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAS3F;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAuB,YAAW,oBAAoB;IACjE,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAE/C;;;;;;;;;OASG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAwGxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAU3C;;;;;;;;;OASG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGnD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic credential resolver for adapter packages (D-ph4-02 · T9357).
|
|
3
|
+
*
|
|
4
|
+
* This module is the canonical credential resolver for adapter packages that
|
|
5
|
+
* cannot import `@cleocode/core` due to the `core → adapters` dependency.
|
|
6
|
+
* It mirrors the first 3 tiers of `core/llm/credentials.ts resolveCredentials()`
|
|
7
|
+
* using only Node.js builtins and `@cleocode/contracts` helpers.
|
|
8
|
+
*
|
|
9
|
+
* ## Resolution tiers (first non-empty match wins)
|
|
10
|
+
* 1. `ANTHROPIC_API_KEY` environment variable
|
|
11
|
+
* 2. `~/.local/share/cleo/anthropic-key` (XDG-aware legacy flat-key file)
|
|
12
|
+
* 3. `~/.claude/.credentials.json` OAuth bearer token
|
|
13
|
+
*
|
|
14
|
+
* Call-sites use the same `resolveCredentials('anthropic').apiKey` pattern
|
|
15
|
+
* as the full 6-tier resolver in `@cleocode/core`, making future migration
|
|
16
|
+
* to the canonical resolver transparent.
|
|
17
|
+
*
|
|
18
|
+
* @module shared/credentials
|
|
19
|
+
* @task T9357
|
|
20
|
+
* @see D-ph4-02
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Result returned by {@link resolveCredentials}.
|
|
24
|
+
*
|
|
25
|
+
* The shape intentionally matches the subset of `CredentialResult` from
|
|
26
|
+
* `@cleocode/core` that adapter call-sites need, so that if this module is
|
|
27
|
+
* ever replaced by a direct core import the call-sites require no changes.
|
|
28
|
+
*/
|
|
29
|
+
export interface ResolvedCredential {
|
|
30
|
+
/** API key or OAuth bearer token, or `null` when no credential was found. */
|
|
31
|
+
apiKey: string | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the Anthropic API key using a 3-tier priority chain.
|
|
35
|
+
*
|
|
36
|
+
* Drop-in compatible with `@cleocode/core` `resolveCredentials('anthropic')`
|
|
37
|
+
* for the subset of fields adapters use (`.apiKey`).
|
|
38
|
+
*
|
|
39
|
+
* Resolution order (first non-empty match wins):
|
|
40
|
+
* 1. `ANTHROPIC_API_KEY` environment variable
|
|
41
|
+
* 2. `~/.local/share/cleo/anthropic-key` (XDG-aware stored key)
|
|
42
|
+
* 3. `~/.claude/.credentials.json` Claude Code OAuth token
|
|
43
|
+
*
|
|
44
|
+
* Never throws — all filesystem errors are caught and treated as "not found".
|
|
45
|
+
*
|
|
46
|
+
* @param provider - Currently only `'anthropic'` is supported.
|
|
47
|
+
* @returns `{ apiKey }` where `apiKey` is `null` when no credential was found.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { resolveCredentials } from '../../shared/credentials.js';
|
|
52
|
+
*
|
|
53
|
+
* const { apiKey } = resolveCredentials('anthropic');
|
|
54
|
+
* if (!apiKey) throw new Error('No Anthropic credential available');
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveCredentials(_provider: 'anthropic'): ResolvedCredential;
|
|
58
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAWH;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,WAAW,GAAG,kBAAkB,CA6B7E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/adapters",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.75",
|
|
4
4
|
"description": "Unified provider adapters for CLEO (Claude Code, OpenCode, Cursor)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"@ai-sdk/anthropic": "^3.0.69",
|
|
16
16
|
"@ai-sdk/openai": "^2.0.53",
|
|
17
17
|
"ai": "^6.0.168",
|
|
18
|
-
"@cleocode/caamp": "2026.5.
|
|
19
|
-
"@cleocode/contracts": "2026.5.
|
|
20
|
-
"@cleocode/paths": "2026.5.
|
|
18
|
+
"@cleocode/caamp": "2026.5.75",
|
|
19
|
+
"@cleocode/contracts": "2026.5.75",
|
|
20
|
+
"@cleocode/paths": "2026.5.75"
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"engines": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.19.15",
|
|
32
32
|
"vitest": "^4.1.4",
|
|
33
|
-
"@cleocode/playbooks": "2026.5.
|
|
33
|
+
"@cleocode/playbooks": "2026.5.75"
|
|
34
34
|
},
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|
|
@@ -23,57 +23,12 @@
|
|
|
23
23
|
* @see ADR-052 — SDK consolidation decision
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
27
|
-
import { homedir } from 'node:os';
|
|
28
|
-
import { join } from 'node:path';
|
|
29
26
|
import type { AdapterSpawnProvider, SpawnContext, SpawnResult } from '@cleocode/contracts';
|
|
30
|
-
import { getErrorMessage
|
|
27
|
+
import { getErrorMessage } from '@cleocode/contracts';
|
|
28
|
+
import { resolveCredentials } from '../shared/credentials.js';
|
|
31
29
|
import { SessionStore } from './session-store.js';
|
|
32
30
|
import { resolveTools } from './tool-bridge.js';
|
|
33
31
|
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// 3-tier Anthropic key resolver
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Resolve the Anthropic API key using a 3-tier priority chain:
|
|
40
|
-
* 1. `ANTHROPIC_API_KEY` environment variable
|
|
41
|
-
* 2. `~/.local/share/cleo/anthropic-key` (user-stored via cleo config)
|
|
42
|
-
* 3. `~/.claude/.credentials.json` → claudeAiOauth.accessToken (Claude Code OAuth)
|
|
43
|
-
*
|
|
44
|
-
* @returns The key/token string, or null if unavailable.
|
|
45
|
-
*/
|
|
46
|
-
function resolveAnthropicApiKey(): string | null {
|
|
47
|
-
// 1. Explicit env var
|
|
48
|
-
const envKey = process.env['ANTHROPIC_API_KEY'];
|
|
49
|
-
if (envKey?.trim()) return envKey;
|
|
50
|
-
|
|
51
|
-
// 2. CLEO global stored key
|
|
52
|
-
try {
|
|
53
|
-
const xdg = process.env['XDG_DATA_HOME'] ?? join(homedir(), '.local', 'share');
|
|
54
|
-
const keyFile = join(xdg, 'cleo', 'anthropic-key');
|
|
55
|
-
if (existsSync(keyFile)) {
|
|
56
|
-
const stored = readFileSync(keyFile, 'utf-8').trim();
|
|
57
|
-
if (stored) return stored;
|
|
58
|
-
}
|
|
59
|
-
} catch {
|
|
60
|
-
// Not available — continue
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 3. Claude Code OAuth token — parsed by the shared contracts helper
|
|
64
|
-
try {
|
|
65
|
-
const credPath = join(homedir(), '.claude', '.credentials.json');
|
|
66
|
-
if (!existsSync(credPath)) return null;
|
|
67
|
-
const raw = readFileSync(credPath, 'utf-8');
|
|
68
|
-
const cred = parseClaudeCodeCredentials(raw);
|
|
69
|
-
return cred?.accessToken ?? null;
|
|
70
|
-
} catch {
|
|
71
|
-
// Credentials file missing or unreadable — not an error
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
32
|
/** Model used when no model is specified in spawn options. */
|
|
78
33
|
const DEFAULT_MODEL = 'claude-sonnet-4-5';
|
|
79
34
|
|
|
@@ -107,7 +62,7 @@ export class ClaudeSDKSpawnProvider implements AdapterSpawnProvider {
|
|
|
107
62
|
* @returns `true` when any Anthropic credential is available
|
|
108
63
|
*/
|
|
109
64
|
async canSpawn(): Promise<boolean> {
|
|
110
|
-
return !!
|
|
65
|
+
return !!resolveCredentials('anthropic').apiKey;
|
|
111
66
|
}
|
|
112
67
|
|
|
113
68
|
/**
|
|
@@ -153,7 +108,7 @@ export class ClaudeSDKSpawnProvider implements AdapterSpawnProvider {
|
|
|
153
108
|
const { createAnthropic } = await import('@ai-sdk/anthropic');
|
|
154
109
|
const { generateText } = await import('ai');
|
|
155
110
|
|
|
156
|
-
const apiKey =
|
|
111
|
+
const apiKey = resolveCredentials('anthropic').apiKey;
|
|
157
112
|
if (!apiKey) {
|
|
158
113
|
this.sessions.remove(instanceId);
|
|
159
114
|
return {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic credential resolver for adapter packages (D-ph4-02 · T9357).
|
|
3
|
+
*
|
|
4
|
+
* This module is the canonical credential resolver for adapter packages that
|
|
5
|
+
* cannot import `@cleocode/core` due to the `core → adapters` dependency.
|
|
6
|
+
* It mirrors the first 3 tiers of `core/llm/credentials.ts resolveCredentials()`
|
|
7
|
+
* using only Node.js builtins and `@cleocode/contracts` helpers.
|
|
8
|
+
*
|
|
9
|
+
* ## Resolution tiers (first non-empty match wins)
|
|
10
|
+
* 1. `ANTHROPIC_API_KEY` environment variable
|
|
11
|
+
* 2. `~/.local/share/cleo/anthropic-key` (XDG-aware legacy flat-key file)
|
|
12
|
+
* 3. `~/.claude/.credentials.json` OAuth bearer token
|
|
13
|
+
*
|
|
14
|
+
* Call-sites use the same `resolveCredentials('anthropic').apiKey` pattern
|
|
15
|
+
* as the full 6-tier resolver in `@cleocode/core`, making future migration
|
|
16
|
+
* to the canonical resolver transparent.
|
|
17
|
+
*
|
|
18
|
+
* @module shared/credentials
|
|
19
|
+
* @task T9357
|
|
20
|
+
* @see D-ph4-02
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { parseClaudeCodeCredentials } from '@cleocode/contracts';
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Types
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Result returned by {@link resolveCredentials}.
|
|
34
|
+
*
|
|
35
|
+
* The shape intentionally matches the subset of `CredentialResult` from
|
|
36
|
+
* `@cleocode/core` that adapter call-sites need, so that if this module is
|
|
37
|
+
* ever replaced by a direct core import the call-sites require no changes.
|
|
38
|
+
*/
|
|
39
|
+
export interface ResolvedCredential {
|
|
40
|
+
/** API key or OAuth bearer token, or `null` when no credential was found. */
|
|
41
|
+
apiKey: string | null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Resolver
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the Anthropic API key using a 3-tier priority chain.
|
|
50
|
+
*
|
|
51
|
+
* Drop-in compatible with `@cleocode/core` `resolveCredentials('anthropic')`
|
|
52
|
+
* for the subset of fields adapters use (`.apiKey`).
|
|
53
|
+
*
|
|
54
|
+
* Resolution order (first non-empty match wins):
|
|
55
|
+
* 1. `ANTHROPIC_API_KEY` environment variable
|
|
56
|
+
* 2. `~/.local/share/cleo/anthropic-key` (XDG-aware stored key)
|
|
57
|
+
* 3. `~/.claude/.credentials.json` Claude Code OAuth token
|
|
58
|
+
*
|
|
59
|
+
* Never throws — all filesystem errors are caught and treated as "not found".
|
|
60
|
+
*
|
|
61
|
+
* @param provider - Currently only `'anthropic'` is supported.
|
|
62
|
+
* @returns `{ apiKey }` where `apiKey` is `null` when no credential was found.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { resolveCredentials } from '../../shared/credentials.js';
|
|
67
|
+
*
|
|
68
|
+
* const { apiKey } = resolveCredentials('anthropic');
|
|
69
|
+
* if (!apiKey) throw new Error('No Anthropic credential available');
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export function resolveCredentials(_provider: 'anthropic'): ResolvedCredential {
|
|
73
|
+
// Tier 1 — explicit env var
|
|
74
|
+
const envKey = process.env['ANTHROPIC_API_KEY'];
|
|
75
|
+
if (envKey?.trim()) return { apiKey: envKey.trim() };
|
|
76
|
+
|
|
77
|
+
// Tier 2 — XDG-aware legacy flat-key file (~/.local/share/cleo/anthropic-key)
|
|
78
|
+
try {
|
|
79
|
+
const xdg = process.env['XDG_DATA_HOME'] ?? join(homedir(), '.local', 'share');
|
|
80
|
+
const keyFile = join(xdg, 'cleo', 'anthropic-key');
|
|
81
|
+
if (existsSync(keyFile)) {
|
|
82
|
+
const stored = readFileSync(keyFile, 'utf-8').trim();
|
|
83
|
+
if (stored) return { apiKey: stored };
|
|
84
|
+
}
|
|
85
|
+
} catch {
|
|
86
|
+
// Not available — continue to next tier
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Tier 3 — Claude Code OAuth token (~/.claude/.credentials.json)
|
|
90
|
+
try {
|
|
91
|
+
const credPath = join(homedir(), '.claude', '.credentials.json');
|
|
92
|
+
if (!existsSync(credPath)) return { apiKey: null };
|
|
93
|
+
const raw = readFileSync(credPath, 'utf-8');
|
|
94
|
+
const cred = parseClaudeCodeCredentials(raw);
|
|
95
|
+
return { apiKey: cred?.accessToken ?? null };
|
|
96
|
+
} catch {
|
|
97
|
+
// Credentials file missing or unreadable — not an error
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return { apiKey: null };
|
|
101
|
+
}
|