@cleocode/contracts 2026.5.67 → 2026.5.69

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 (54) hide show
  1. package/dist/__tests__/credentials.test.d.ts +10 -0
  2. package/dist/__tests__/credentials.test.d.ts.map +1 -0
  3. package/dist/__tests__/credentials.test.js +100 -0
  4. package/dist/__tests__/credentials.test.js.map +1 -0
  5. package/dist/__tests__/llm-config-schema.test.d.ts +6 -6
  6. package/dist/__tests__/llm-config-schema.test.js +9 -13
  7. package/dist/__tests__/llm-config-schema.test.js.map +1 -1
  8. package/dist/config.d.ts +32 -54
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/credentials.d.ts +75 -0
  11. package/dist/credentials.d.ts.map +1 -0
  12. package/dist/credentials.js +79 -0
  13. package/dist/credentials.js.map +1 -0
  14. package/dist/index.d.ts +8 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/llm/failover-reason.d.ts +1 -1
  19. package/dist/llm/interfaces.d.ts +1 -0
  20. package/dist/llm/interfaces.d.ts.map +1 -1
  21. package/dist/llm/normalized-response.d.ts +10 -0
  22. package/dist/llm/normalized-response.d.ts.map +1 -1
  23. package/dist/llm/oauth.d.ts +125 -0
  24. package/dist/llm/oauth.d.ts.map +1 -0
  25. package/dist/llm/oauth.js +12 -0
  26. package/dist/llm/oauth.js.map +1 -0
  27. package/dist/llm/plugin-llm.d.ts +93 -0
  28. package/dist/llm/plugin-llm.d.ts.map +1 -0
  29. package/dist/llm/plugin-llm.js +65 -0
  30. package/dist/llm/plugin-llm.js.map +1 -0
  31. package/dist/llm/provider-profile.d.ts +23 -0
  32. package/dist/llm/provider-profile.d.ts.map +1 -1
  33. package/dist/memory/context-engine.d.ts +67 -0
  34. package/dist/memory/context-engine.d.ts.map +1 -0
  35. package/dist/memory/context-engine.js +15 -0
  36. package/dist/memory/context-engine.js.map +1 -0
  37. package/dist/operations/llm.d.ts +43 -6
  38. package/dist/operations/llm.d.ts.map +1 -1
  39. package/dist/operations/llm.js +0 -4
  40. package/dist/operations/llm.js.map +1 -1
  41. package/package.json +10 -2
  42. package/src/__tests__/credentials.test.ts +122 -0
  43. package/src/__tests__/llm-config-schema.test.ts +9 -13
  44. package/src/config.ts +37 -55
  45. package/src/credentials.ts +114 -0
  46. package/src/index.ts +22 -7
  47. package/src/llm/failover-reason.ts +1 -1
  48. package/src/llm/interfaces.ts +13 -0
  49. package/src/llm/normalized-response.ts +10 -0
  50. package/src/llm/oauth.ts +144 -0
  51. package/src/llm/plugin-llm.ts +128 -0
  52. package/src/llm/provider-profile.ts +25 -0
  53. package/src/memory/context-engine.ts +78 -0
  54. package/src/operations/llm.ts +50 -6
@@ -0,0 +1,15 @@
1
+ /**
2
+ * ContextEngine interface contract — canonical location.
3
+ *
4
+ * Defines the compression contract used by {@link LlmExecutor} to keep
5
+ * session history within the model's context budget. An engine is injected
6
+ * at executor construction time; when absent the executor silently skips
7
+ * all compression checks.
8
+ *
9
+ * @module memory/context-engine
10
+ * @task T9304
11
+ * @epic T9261 T-LLM-CRED-CENTRALIZATION
12
+ * @see ADR-072 §"LlmExecutor — agent-loop level"
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=context-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-engine.js","sourceRoot":"","sources":["../../src/memory/context-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -173,15 +173,13 @@ export interface CredentialResultWire {
173
173
  * Resolution chain order:
174
174
  * 1. `role` — `config.llm.roles[role]` (explicit override)
175
175
  * 2. `default` — `config.llm.default` (canonical default)
176
- * 3. `daemon-legacy` `config.llm.daemon` (deprecated alias)
177
- * 4. `implicit-fallback` — hard-coded fallback inside the resolver
176
+ * 3. `implicit-fallback` hard-coded fallback inside the resolver
178
177
  *
179
- * Useful for `cleo llm whoami` diagnostics and for migration tooling that
180
- * needs to identify call-sites still on the legacy `daemon` block.
178
+ * Useful for `cleo llm whoami` diagnostics.
181
179
  *
182
- * @task T9255
180
+ * @task T9306
183
181
  */
184
- export type ResolutionSource = 'role' | 'default' | 'daemon-legacy' | 'implicit-fallback';
182
+ export type ResolutionSource = 'role' | 'default' | 'implicit-fallback';
185
183
  /**
186
184
  * Result envelope returned by `resolveLLMForRole(role)`.
187
185
  *
@@ -497,4 +495,43 @@ export interface LlmWhoamiResult {
497
495
  /** One entry per role resolved (filtered by `params.role` when set). */
498
496
  entries: LlmWhoamiEntry[];
499
497
  }
498
+ /**
499
+ * Resolved credential source for a single LLM provider.
500
+ *
501
+ * Mirrors the subset of `CredentialSource` relevant for human-facing status
502
+ * output. `'none'` means no credential was found at any tier.
503
+ *
504
+ * @task T9323
505
+ */
506
+ export type LlmProviderSourceWire = 'env' | 'cred-file' | 'claude-creds' | 'config' | 'none';
507
+ /**
508
+ * Per-provider status entry emitted by `cleo memory llm-status`.
509
+ *
510
+ * @task T9323
511
+ */
512
+ export interface LlmProviderStatusEntry {
513
+ /** Provider identifier (e.g. `'anthropic'`, `'kimi-code'`). */
514
+ provider: string;
515
+ /** Which credential tier resolved the key, or `'none'` if unavailable. */
516
+ resolvedSource: LlmProviderSourceWire;
517
+ /** `true` when a usable credential was found. */
518
+ hasCredential: boolean;
519
+ }
520
+ /**
521
+ * Result envelope for `memory.llm-status` (query).
522
+ *
523
+ * @task T9323
524
+ */
525
+ export interface LlmStatusResult {
526
+ /** Legacy anthropic-only resolved source (kept for backward compat). */
527
+ resolvedSource: string;
528
+ /** `true` when an Anthropic credential is available (legacy compat field). */
529
+ extractionEnabled: boolean;
530
+ /** ISO timestamp of the most recent extraction run, or `null`. */
531
+ lastExtractionRun: string | null;
532
+ /** Suggested test command. */
533
+ testCommand: string;
534
+ /** Per-provider status for all known OAuth providers. */
535
+ providers: LlmProviderStatusEntry[];
536
+ }
500
537
  //# sourceMappingURL=llm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/operations/llm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/operations/llm.ts"],"names":[],"mappings":"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"}
@@ -9,8 +9,4 @@
9
9
  * @epic T1386
10
10
  */
11
11
  export {};
12
- // ProviderProfile interface lives in ./llm/provider-profile.ts (T9262).
13
- // The generated catalog (packages/core/src/llm/generated/provider-profiles.ts)
14
- // imports the canonical type from the contracts package and emits each
15
- // generated entry as a plain ProviderProfile literal.
16
12
  //# sourceMappingURL=llm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/operations/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;AA6iBH,wEAAwE;AACxE,+EAA+E;AAC/E,uEAAuE;AACvE,sDAAsD"}
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/operations/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/contracts",
3
- "version": "2026.5.67",
3
+ "version": "2026.5.69",
4
4
  "description": "Domain types, interfaces, and contracts for the CLEO ecosystem",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -65,6 +65,14 @@
65
65
  "./llm/*.js": {
66
66
  "types": "./dist/llm/*.d.ts",
67
67
  "import": "./dist/llm/*.js"
68
+ },
69
+ "./memory/*": {
70
+ "types": "./dist/memory/*.d.ts",
71
+ "import": "./dist/memory/*.js"
72
+ },
73
+ "./memory/*.js": {
74
+ "types": "./dist/memory/*.d.ts",
75
+ "import": "./dist/memory/*.js"
68
76
  }
69
77
  },
70
78
  "engines": {
@@ -90,7 +98,7 @@
90
98
  "dependencies": {
91
99
  "zod": "^4.3.6",
92
100
  "zod-to-json-schema": "^3.25.2",
93
- "@cleocode/lafs": "2026.5.67"
101
+ "@cleocode/lafs": "2026.5.69"
94
102
  },
95
103
  "scripts": {
96
104
  "build": "tsc -b --force && node scripts/emit-schemas.mjs",
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Smoke tests for `parseClaudeCodeCredentials()` in @cleocode/contracts.
3
+ *
4
+ * Covers both OAuth-shaped and api-key-shaped JSON, plus edge cases
5
+ * (malformed input, expired tokens, missing fields).
6
+ *
7
+ * @task T9307
8
+ */
9
+
10
+ import { describe, expect, it } from 'vitest';
11
+ import { parseClaudeCodeCredentials } from '../credentials.js';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Helpers
15
+ // ---------------------------------------------------------------------------
16
+
17
+ function makeCreds(overrides: Record<string, unknown> = {}): string {
18
+ return JSON.stringify({
19
+ claudeAiOauth: {
20
+ accessToken: 'sk-ant-oat-test-token',
21
+ expiresAt: Date.now() + 3_600_000,
22
+ ...overrides,
23
+ },
24
+ });
25
+ }
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // OAuth-shaped credentials
29
+ // ---------------------------------------------------------------------------
30
+
31
+ describe('OAuth-shaped credentials', () => {
32
+ it('returns accessToken for valid OAuth JSON', () => {
33
+ const result = parseClaudeCodeCredentials(makeCreds());
34
+ expect(result).not.toBeNull();
35
+ expect(result?.accessToken).toBe('sk-ant-oat-test-token');
36
+ });
37
+
38
+ it('returns expiresAt when present', () => {
39
+ const expiresAt = Date.now() + 7_200_000;
40
+ const result = parseClaudeCodeCredentials(makeCreds({ expiresAt }));
41
+ expect(result?.expiresAt).toBe(expiresAt);
42
+ });
43
+
44
+ it('returns refreshToken when present', () => {
45
+ const result = parseClaudeCodeCredentials(
46
+ makeCreds({ refreshToken: 'sk-ant-ort-refresh-token' }),
47
+ );
48
+ expect(result?.refreshToken).toBe('sk-ant-ort-refresh-token');
49
+ });
50
+
51
+ it('returns null for expired token', () => {
52
+ const result = parseClaudeCodeCredentials(makeCreds({ expiresAt: Date.now() - 1 }));
53
+ expect(result).toBeNull();
54
+ });
55
+
56
+ it('omits expiresAt when not provided', () => {
57
+ const raw = JSON.stringify({
58
+ claudeAiOauth: { accessToken: 'sk-ant-oat-no-expiry' },
59
+ });
60
+ const result = parseClaudeCodeCredentials(raw);
61
+ expect(result?.accessToken).toBe('sk-ant-oat-no-expiry');
62
+ expect(result?.expiresAt).toBeUndefined();
63
+ });
64
+
65
+ it('accepts a Buffer input', () => {
66
+ const buf = Buffer.from(makeCreds(), 'utf-8');
67
+ const result = parseClaudeCodeCredentials(buf);
68
+ expect(result?.accessToken).toBe('sk-ant-oat-test-token');
69
+ });
70
+ });
71
+
72
+ // ---------------------------------------------------------------------------
73
+ // Api-key-shaped / missing claudeAiOauth block
74
+ // ---------------------------------------------------------------------------
75
+
76
+ describe('Non-OAuth / missing block', () => {
77
+ it('returns null when claudeAiOauth block is absent', () => {
78
+ const raw = JSON.stringify({ someOtherKey: 'value' });
79
+ expect(parseClaudeCodeCredentials(raw)).toBeNull();
80
+ });
81
+
82
+ it('returns null when accessToken is empty string', () => {
83
+ const raw = JSON.stringify({ claudeAiOauth: { accessToken: '' } });
84
+ expect(parseClaudeCodeCredentials(raw)).toBeNull();
85
+ });
86
+
87
+ it('returns null when accessToken is whitespace only', () => {
88
+ const raw = JSON.stringify({ claudeAiOauth: { accessToken: ' ' } });
89
+ expect(parseClaudeCodeCredentials(raw)).toBeNull();
90
+ });
91
+
92
+ it('returns null when accessToken field is missing', () => {
93
+ const raw = JSON.stringify({ claudeAiOauth: { expiresAt: Date.now() + 3600 } });
94
+ expect(parseClaudeCodeCredentials(raw)).toBeNull();
95
+ });
96
+ });
97
+
98
+ // ---------------------------------------------------------------------------
99
+ // Malformed / edge-case input
100
+ // ---------------------------------------------------------------------------
101
+
102
+ describe('Malformed input', () => {
103
+ it('returns null for empty string', () => {
104
+ expect(parseClaudeCodeCredentials('')).toBeNull();
105
+ });
106
+
107
+ it('returns null for invalid JSON', () => {
108
+ expect(parseClaudeCodeCredentials('not-json')).toBeNull();
109
+ });
110
+
111
+ it('returns null for JSON null', () => {
112
+ expect(parseClaudeCodeCredentials('null')).toBeNull();
113
+ });
114
+
115
+ it('returns null for JSON array', () => {
116
+ expect(parseClaudeCodeCredentials('[]')).toBeNull();
117
+ });
118
+
119
+ it('returns null for empty Buffer', () => {
120
+ expect(parseClaudeCodeCredentials(Buffer.alloc(0))).toBeNull();
121
+ });
122
+ });
@@ -3,27 +3,26 @@
3
3
  *
4
4
  * Asserts that:
5
5
  *
6
- * 1. A literal `LlmConfig` object containing the new `default`, `roles`, and
7
- * the legacy `daemon` fields typechecks and survives a JSON
8
- * serialize/deserialize cycle without structural loss.
6
+ * 1. A literal `LlmConfig` object containing the `default` and `roles` fields
7
+ * typechecks and survives a JSON serialize/deserialize cycle without
8
+ * structural loss.
9
9
  * 2. All five `RoleName` values (`extraction`, `consolidation`, `derivation`,
10
10
  * `hygiene`, `judgement`) are accepted as keys of `roles`.
11
11
  * 3. Omitting `default` and/or `roles` still typechecks (both are optional).
12
12
  *
13
- * These tests guard the Phase 2 schema extension of
14
- * T-LLM-CRED-CENTRALIZATION against accidental regressions.
13
+ * These tests guard the Phase 4 schema cleanup of T-LLM-CRED-CENTRALIZATION
14
+ * (T9306 — daemon field removed) against accidental regressions.
15
15
  *
16
- * @task T9256
16
+ * @task T9306
17
17
  * @epic T-LLM-CRED-CENTRALIZATION
18
18
  */
19
19
 
20
20
  import { describe, expect, it } from 'vitest';
21
21
  import type { LlmConfig, LlmDefaultConfig, LlmRoleConfig, RoleName } from '../config.js';
22
22
 
23
- describe('LlmConfig — Phase 2 schema extension (T9256)', () => {
24
- it('accepts a fully-populated config with default, roles, and legacy daemon', () => {
23
+ describe('LlmConfig — Phase 4 schema cleanup (T9306)', () => {
24
+ it('accepts a fully-populated config with default and roles', () => {
25
25
  const cfg: LlmConfig = {
26
- daemon: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
27
26
  providers: {
28
27
  anthropic: { apiKey: 'sk-test-anthropic' },
29
28
  openai: { apiKey: 'sk-test-openai' },
@@ -102,13 +101,10 @@ describe('LlmConfig — Phase 2 schema extension (T9256)', () => {
102
101
  });
103
102
 
104
103
  it('typechecks when default and roles are both omitted', () => {
105
- const cfg: LlmConfig = {
106
- daemon: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
107
- };
104
+ const cfg: LlmConfig = {};
108
105
 
109
106
  expect(cfg.default).toBeUndefined();
110
107
  expect(cfg.roles).toBeUndefined();
111
- expect(cfg.daemon?.provider).toBe('anthropic');
112
108
  });
113
109
 
114
110
  it('typechecks an empty LlmConfig (all fields optional)', () => {
package/src/config.ts CHANGED
@@ -374,30 +374,7 @@ export interface LlmProviderEntry {
374
374
  }
375
375
 
376
376
  /**
377
- * Daemon LLM configurationwhich provider + model the CLEO daemon
378
- * (sentient tick, dream-cycle, BRAIN extraction, etc.) uses by default.
379
- *
380
- * Written via:
381
- * cleo config llm.daemon.provider <provider>
382
- * cleo config llm.daemon.model <model-id>
383
- *
384
- * @defaultValue { provider: 'anthropic', model: 'claude-sonnet-4-6' }
385
- */
386
- export interface DaemonLLMConfig {
387
- /**
388
- * LLM provider transport used by daemon loops.
389
- * @defaultValue 'anthropic'
390
- */
391
- provider: ModelTransport;
392
- /**
393
- * Full model identifier for the selected provider.
394
- * @defaultValue 'claude-sonnet-4-6'
395
- */
396
- model: string;
397
- }
398
-
399
- /**
400
- * Canonical model transport identifier — re-export of {@link ModelTransport}
377
+ * Config-layer transport identifierre-export of {@link ModelTransport}
401
378
  * from `operations/llm.ts` so config-layer types stay in lock-step with the
402
379
  * operations layer with no risk of drift.
403
380
  *
@@ -405,33 +382,45 @@ export interface DaemonLLMConfig {
405
382
  * T-LLM-CRED Phase 2 DRY/SOLID review (P1-2). Adding a new transport now
406
383
  * requires editing only `operations/llm.ts`.
407
384
  *
385
+ * **Disambiguation**: This is the *config-level* alias for the
386
+ * `ModelTransport` string-literal union (`'anthropic' | 'openai' | ...`).
387
+ * It is intentionally distinct from the `LlmTransport` *interface* defined
388
+ * in `packages/contracts/src/llm/normalized-response.ts` (Phase 4 wire-level
389
+ * protocol). Renamed from `LlmTransport` → `LlmProviderTransport` in T9308
390
+ * to eliminate the name collision.
391
+ *
408
392
  * @task T-LLM-CRED-CENTRALIZATION Phase 2 — DRY review P1-2
393
+ * @see T9308 — disambiguation rename
409
394
  */
410
- export type LlmTransport = ModelTransport;
395
+ export type LlmProviderTransport = ModelTransport;
411
396
 
412
397
  /**
413
398
  * Logical LLM role name used by role-aware resolvers (BRAIN, sentient, etc.).
414
399
  *
415
400
  * Each role can pin its own provider + model + credential label, with
416
- * resolution falling back to `LlmConfig.default` and finally to the legacy
417
- * `LlmConfig.daemon` block.
401
+ * resolution falling back to `LlmConfig.default`.
418
402
  *
419
- * @task T-LLM-CRED-CENTRALIZATION Phase 2 (T9256)
403
+ * @task T-LLM-CRED-CENTRALIZATION Phase 4 (T9306)
420
404
  */
421
- export type RoleName = 'extraction' | 'consolidation' | 'derivation' | 'hygiene' | 'judgement';
405
+ export type RoleName =
406
+ | 'extraction'
407
+ | 'consolidation'
408
+ | 'derivation'
409
+ | 'hygiene'
410
+ | 'judgement'
411
+ /** Sandbox role for plugin-scoped single-turn calls (T9305). */
412
+ | 'plugin'
413
+ /** Context-compression role — uses a cheap model (haiku) for summarization (T9304). */
414
+ | 'compression';
422
415
 
423
416
  /**
424
417
  * Canonical default LLM target for unscoped (non-role) calls.
425
418
  *
426
- * Replaces the role previously played by `LlmConfig.daemon`. The `daemon`
427
- * field stays as a deprecated alias for one release cycle to give downstream
428
- * consumers time to migrate.
429
- *
430
- * @task T-LLM-CRED-CENTRALIZATION Phase 2 (T9256)
419
+ * @task T-LLM-CRED-CENTRALIZATION Phase 4 (T9306)
431
420
  */
432
421
  export interface LlmDefaultConfig {
433
422
  /** LLM provider transport for the default model. */
434
- provider: LlmTransport;
423
+ provider: LlmProviderTransport;
435
424
  /** Full model identifier for the selected provider. */
436
425
  model: string;
437
426
  }
@@ -448,7 +437,7 @@ export interface LlmDefaultConfig {
448
437
  */
449
438
  export interface LlmRoleConfig {
450
439
  /** LLM provider transport for this role. */
451
- provider: LlmTransport;
440
+ provider: LlmProviderTransport;
452
441
  /** Full model identifier for the selected provider. */
453
442
  model: string;
454
443
  /**
@@ -465,39 +454,32 @@ export interface LlmRoleConfig {
465
454
  * Stored at `llm` in config.json.
466
455
  *
467
456
  * Resolution order for role-scoped calls:
468
- * `roles[role]` → `default` → `daemon` (legacy).
457
+ * `roles[role]` → `default` → implicit fallback.
458
+ *
459
+ * Note: configs that still carry a `llm.daemon` key are silently ignored
460
+ * at parse time — they will not cause a crash. Migration: remove the key
461
+ * and add `llm.default` or `llm.roles.<role>` instead.
462
+ *
463
+ * @task T-LLM-CRED-CENTRALIZATION Phase 4 (T9306)
469
464
  */
470
465
  export interface LlmConfig {
471
- /**
472
- * Daemon LLM settings (provider + model for background loops).
473
- *
474
- * @deprecated Use `default` instead. Retained as a fallback alias for
475
- * one release cycle (T-LLM-CRED-CENTRALIZATION Phase 2 · T9256). New
476
- * code must read `default` first and only fall through to `daemon` when
477
- * `default` is absent.
478
- * @defaultValue { provider: 'anthropic', model: 'claude-sonnet-4-6' }
479
- */
480
- daemon?: DaemonLLMConfig;
481
466
  /**
482
467
  * Per-provider API key overrides.
483
468
  * Keys are provider names: 'anthropic' | 'openai' | 'gemini' | 'moonshot'.
484
469
  */
485
470
  providers?: Record<string, LlmProviderEntry>;
486
471
  /**
487
- * Canonical default LLM for unscoped calls. Replaces the role previously
488
- * played by `daemon`, which stays as a deprecated alias for one release
489
- * cycle.
472
+ * Canonical default LLM for unscoped calls.
490
473
  *
491
- * @task T-LLM-CRED-CENTRALIZATION Phase 2 (T9256)
474
+ * @task T-LLM-CRED-CENTRALIZATION Phase 4 (T9306)
492
475
  */
493
476
  default?: LlmDefaultConfig;
494
477
  /**
495
- * Per-role LLM overrides. Each role optionally pins to a credential
496
- * label.
478
+ * Per-role LLM overrides. Each role optionally pins to a credential label.
497
479
  *
498
- * Resolution order: `roles[role]` → `default` → `daemon` (legacy).
480
+ * Resolution order: `roles[role]` → `default` → implicit fallback.
499
481
  *
500
- * @task T-LLM-CRED-CENTRALIZATION Phase 2 (T9256)
482
+ * @task T-LLM-CRED-CENTRALIZATION Phase 4 (T9306)
501
483
  */
502
484
  roles?: Partial<Record<RoleName, LlmRoleConfig>>;
503
485
  }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Pure credential-parsing helpers for the CLEO LLM layer.
3
+ *
4
+ * This module is a LEAF — it has NO imports from @cleocode/core or any
5
+ * other runtime package. It exists so adapter packages can parse Claude Code
6
+ * OAuth credentials without creating a circular dependency on @cleocode/core.
7
+ *
8
+ * ## What lives here
9
+ * - `ClaudeCodeCredential` — shape of `~/.claude/.credentials.json`
10
+ * - `parseClaudeCodeCredentials()` — pure JSON parser + expiry check
11
+ *
12
+ * ## What does NOT live here
13
+ * - Filesystem reads (those belong in core/llm/credentials.ts)
14
+ * - Caching (belongs in core)
15
+ * - Multi-tier resolution (belongs in core)
16
+ *
17
+ * @module credentials
18
+ * @task T9307
19
+ */
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Types
23
+ // ---------------------------------------------------------------------------
24
+
25
+ /**
26
+ * The `claudeAiOauth` block found inside `~/.claude/.credentials.json`.
27
+ */
28
+ export interface ClaudeCodeOAuthBlock {
29
+ /** Short-lived bearer token for Anthropic API calls. */
30
+ accessToken: string;
31
+ /** Unix-millisecond timestamp after which the token is invalid. Optional. */
32
+ expiresAt?: number;
33
+ /** Refresh token for obtaining new access tokens. Optional. */
34
+ refreshToken?: string;
35
+ }
36
+
37
+ /**
38
+ * Parsed result returned by `parseClaudeCodeCredentials()`.
39
+ *
40
+ * All fields mirror `ClaudeCodeOAuthBlock` but `accessToken` is always
41
+ * present (a null return indicates the file was absent, malformed, or expired).
42
+ */
43
+ export interface ParsedClaudeCodeCredential {
44
+ /** Bearer access token for the Anthropic API. */
45
+ accessToken: string;
46
+ /** Expiry as a Unix millisecond timestamp, if provided. */
47
+ expiresAt?: number;
48
+ /** Refresh token, if present in the credentials file. */
49
+ refreshToken?: string;
50
+ }
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Parser
54
+ // ---------------------------------------------------------------------------
55
+
56
+ /**
57
+ * Parse the contents of `~/.claude/.credentials.json` and extract the OAuth
58
+ * credential block.
59
+ *
60
+ * This is a **pure** helper: it accepts a `Buffer | string` (the raw file
61
+ * content) and returns the parsed credential or `null`. It never reads the
62
+ * filesystem or accesses environment variables.
63
+ *
64
+ * Expiry is checked using `Date.now()` — tokens whose `expiresAt` is in the
65
+ * past are treated as absent and `null` is returned.
66
+ *
67
+ * @param buf - Raw UTF-8 contents of the credentials file.
68
+ * @returns Parsed credential object, or `null` when the file is malformed,
69
+ * the OAuth block is absent, or the token is expired.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * import { readFileSync } from 'node:fs';
74
+ * import { join } from 'node:path';
75
+ * import { homedir } from 'node:os';
76
+ * import { parseClaudeCodeCredentials } from '@cleocode/contracts';
77
+ *
78
+ * const raw = readFileSync(join(homedir(), '.claude', '.credentials.json'));
79
+ * const cred = parseClaudeCodeCredentials(raw);
80
+ * if (cred) {
81
+ * console.log('token:', cred.accessToken);
82
+ * }
83
+ * ```
84
+ */
85
+ export function parseClaudeCodeCredentials(
86
+ buf: Buffer | string,
87
+ ): ParsedClaudeCodeCredential | null {
88
+ try {
89
+ const text = typeof buf === 'string' ? buf : buf.toString('utf-8');
90
+ const raw = JSON.parse(text) as Record<string, unknown>;
91
+ const oauth = raw['claudeAiOauth'];
92
+ if (!oauth || typeof oauth !== 'object') return null;
93
+
94
+ const block = oauth as Record<string, unknown>;
95
+ const accessToken = block['accessToken'];
96
+ if (typeof accessToken !== 'string' || !accessToken.trim()) return null;
97
+
98
+ const expiresAt = typeof block['expiresAt'] === 'number' ? block['expiresAt'] : undefined;
99
+ if (expiresAt !== undefined && Date.now() > expiresAt) return null;
100
+
101
+ const refreshToken =
102
+ typeof block['refreshToken'] === 'string' && block['refreshToken'].trim()
103
+ ? block['refreshToken']
104
+ : undefined;
105
+
106
+ return {
107
+ accessToken: accessToken.trim(),
108
+ ...(expiresAt !== undefined ? { expiresAt } : {}),
109
+ ...(refreshToken !== undefined ? { refreshToken } : {}),
110
+ };
111
+ } catch {
112
+ return null;
113
+ }
114
+ }