@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.
- package/dist/__tests__/credentials.test.d.ts +10 -0
- package/dist/__tests__/credentials.test.d.ts.map +1 -0
- package/dist/__tests__/credentials.test.js +100 -0
- package/dist/__tests__/credentials.test.js.map +1 -0
- package/dist/__tests__/llm-config-schema.test.d.ts +6 -6
- package/dist/__tests__/llm-config-schema.test.js +9 -13
- package/dist/__tests__/llm-config-schema.test.js.map +1 -1
- package/dist/config.d.ts +32 -54
- package/dist/config.d.ts.map +1 -1
- package/dist/credentials.d.ts +75 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +79 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/failover-reason.d.ts +1 -1
- package/dist/llm/interfaces.d.ts +1 -0
- package/dist/llm/interfaces.d.ts.map +1 -1
- package/dist/llm/normalized-response.d.ts +10 -0
- package/dist/llm/normalized-response.d.ts.map +1 -1
- package/dist/llm/oauth.d.ts +125 -0
- package/dist/llm/oauth.d.ts.map +1 -0
- package/dist/llm/oauth.js +12 -0
- package/dist/llm/oauth.js.map +1 -0
- package/dist/llm/plugin-llm.d.ts +93 -0
- package/dist/llm/plugin-llm.d.ts.map +1 -0
- package/dist/llm/plugin-llm.js +65 -0
- package/dist/llm/plugin-llm.js.map +1 -0
- package/dist/llm/provider-profile.d.ts +23 -0
- package/dist/llm/provider-profile.d.ts.map +1 -1
- package/dist/memory/context-engine.d.ts +67 -0
- package/dist/memory/context-engine.d.ts.map +1 -0
- package/dist/memory/context-engine.js +15 -0
- package/dist/memory/context-engine.js.map +1 -0
- package/dist/operations/llm.d.ts +43 -6
- package/dist/operations/llm.d.ts.map +1 -1
- package/dist/operations/llm.js +0 -4
- package/dist/operations/llm.js.map +1 -1
- package/package.json +10 -2
- package/src/__tests__/credentials.test.ts +122 -0
- package/src/__tests__/llm-config-schema.test.ts +9 -13
- package/src/config.ts +37 -55
- package/src/credentials.ts +114 -0
- package/src/index.ts +22 -7
- package/src/llm/failover-reason.ts +1 -1
- package/src/llm/interfaces.ts +13 -0
- package/src/llm/normalized-response.ts +10 -0
- package/src/llm/oauth.ts +144 -0
- package/src/llm/plugin-llm.ts +128 -0
- package/src/llm/provider-profile.ts +25 -0
- package/src/memory/context-engine.ts +78 -0
- 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"}
|
package/dist/operations/llm.d.ts
CHANGED
|
@@ -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. `
|
|
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
|
|
180
|
-
* needs to identify call-sites still on the legacy `daemon` block.
|
|
178
|
+
* Useful for `cleo llm whoami` diagnostics.
|
|
181
179
|
*
|
|
182
|
-
* @task
|
|
180
|
+
* @task T9306
|
|
183
181
|
*/
|
|
184
|
-
export type ResolutionSource = 'role' | 'default' | '
|
|
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":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAEpE,mDAAmD;AACnD,MAAM,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE5D,wCAAwC;AACxC,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,IAAI,EAAE,qBAAqB,CAAC;IAC5B,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,SAAS,EAAE,cAAc,CAAC;IAC1B,uFAAuF;IACvF,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iDAAiD;IACjD,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChD,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAChC,6BAA6B;IAC7B,WAAW,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvC,yDAAyD;IACzD,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC;IAChD;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IAC7C,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,MAAM;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB,EAAE,MAAM,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAYD;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,GAC5B,UAAU,GACV,KAAK,GACL,WAAW,GACX,cAAc,GACd,eAAe,GACf,gBAAgB,CAAC;AAErB;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,QAAQ,EAAE,cAAc,CAAC;IACzB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gFAAgF;IAChF,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACzC,6DAA6D;IAC7D,QAAQ,EAAE,YAAY,CAAC;CACxB;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,mBAAmB,CAAC;AAExE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,QAAQ,EAAE,cAAc,CAAC;IACzB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACxC,kDAAkD;IAClD,MAAM,EAAE,gBAAgB,CAAC;IACzB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAeD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjE;;;;;;;;GAQG;AACH,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,GAAG,YAAY,GAAG,cAAc,CAAC;AAElG;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,4CAA4C;IAC5C,QAAQ,EAAE,cAAc,CAAC;IACzB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,mDAAmD;IACnD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gDAAgD;IAChD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,UAAU,EAAE,uBAAuB,CAAC;IACpC,2EAA2E;IAC3E,gBAAgB,EAAE,kBAAkB,CAAC;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,WAAW,EAAE,uBAAuB,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,cAAc,CAAC;IACzB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,QAAQ,EAAE,cAAc,CAAC;IACzB,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,QAAQ,EAAE,cAAc,CAAC;IACzB,uEAAuE;IACvE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wEAAwE;IACxE,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,cAAc,CAAC;IACzB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,QAAQ,EAAE,cAAc,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,2EAA2E;IAC3E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,wCAAwC;IACxC,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,QAAQ,EAAE,cAAc,CAAC;IACzB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,kFAAkF;IAClF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,gBAAgB,EAAE,oBAAoB,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,EAAE,cAAc,CAAC;IACzB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,MAAM,EAAE,gBAAgB,CAAC;IACzB,qEAAqE;IACrE,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,0EAA0E;IAC1E,gBAAgB,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACnD,wDAAwD;IACxD,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAWD;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,cAAc,EAAE,qBAAqB,CAAC;IACtC,iDAAiD;IACjD,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,SAAS,EAAE,sBAAsB,EAAE,CAAC;CACrC"}
|
package/dist/operations/llm.js
CHANGED
|
@@ -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
|
|
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.
|
|
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.
|
|
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
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
|
14
|
-
*
|
|
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
|
|
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
|
|
24
|
-
it('accepts a fully-populated config with default
|
|
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
|
-
*
|
|
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 identifier — re-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
|
|
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
|
|
417
|
-
* `LlmConfig.daemon` block.
|
|
401
|
+
* resolution falling back to `LlmConfig.default`.
|
|
418
402
|
*
|
|
419
|
-
* @task T-LLM-CRED-CENTRALIZATION Phase
|
|
403
|
+
* @task T-LLM-CRED-CENTRALIZATION Phase 4 (T9306)
|
|
420
404
|
*/
|
|
421
|
-
export type RoleName =
|
|
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
|
-
*
|
|
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:
|
|
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:
|
|
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` →
|
|
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.
|
|
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
|
|
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` →
|
|
480
|
+
* Resolution order: `roles[role]` → `default` → implicit fallback.
|
|
499
481
|
*
|
|
500
|
-
* @task T-LLM-CRED-CENTRALIZATION Phase
|
|
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
|
+
}
|