@calliopelabs/cli 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/README.md +13 -0
  2. package/dist/approvals/request.d.ts.map +1 -1
  3. package/dist/approvals/request.js +10 -0
  4. package/dist/approvals/request.js.map +1 -1
  5. package/dist/auth/chatgpt/fallback.d.ts +31 -0
  6. package/dist/auth/chatgpt/fallback.d.ts.map +1 -0
  7. package/dist/auth/chatgpt/fallback.js +111 -0
  8. package/dist/auth/chatgpt/fallback.js.map +1 -0
  9. package/dist/auth/chatgpt/index.d.ts +6 -0
  10. package/dist/auth/chatgpt/index.d.ts.map +1 -0
  11. package/dist/auth/chatgpt/index.js +6 -0
  12. package/dist/auth/chatgpt/index.js.map +1 -0
  13. package/dist/auth/chatgpt/login.d.ts +4 -0
  14. package/dist/auth/chatgpt/login.d.ts.map +1 -0
  15. package/dist/auth/chatgpt/login.js +82 -0
  16. package/dist/auth/chatgpt/login.js.map +1 -0
  17. package/dist/auth/chatgpt/protocol.d.ts +24 -0
  18. package/dist/auth/chatgpt/protocol.d.ts.map +1 -0
  19. package/dist/auth/chatgpt/protocol.js +71 -0
  20. package/dist/auth/chatgpt/protocol.js.map +1 -0
  21. package/dist/auth/chatgpt/session.d.ts +24 -0
  22. package/dist/auth/chatgpt/session.d.ts.map +1 -0
  23. package/dist/auth/chatgpt/session.js +101 -0
  24. package/dist/auth/chatgpt/session.js.map +1 -0
  25. package/dist/auth/chatgpt/store.d.ts +28 -0
  26. package/dist/auth/chatgpt/store.d.ts.map +1 -0
  27. package/dist/auth/chatgpt/store.js +75 -0
  28. package/dist/auth/chatgpt/store.js.map +1 -0
  29. package/dist/auth/cli.d.ts +2 -0
  30. package/dist/auth/cli.d.ts.map +1 -0
  31. package/dist/auth/cli.js +38 -0
  32. package/dist/auth/cli.js.map +1 -0
  33. package/dist/auth/index.d.ts +2 -0
  34. package/dist/auth/index.d.ts.map +1 -0
  35. package/dist/auth/index.js +2 -0
  36. package/dist/auth/index.js.map +1 -0
  37. package/dist/bin.d.ts.map +1 -1
  38. package/dist/bin.js +25 -0
  39. package/dist/bin.js.map +1 -1
  40. package/dist/brain/exchange.d.ts.map +1 -1
  41. package/dist/brain/exchange.js +3 -1
  42. package/dist/brain/exchange.js.map +1 -1
  43. package/dist/brain/kg-export.d.ts +1 -1
  44. package/dist/brain/kg.d.ts +1 -1
  45. package/dist/brain/kg.d.ts.map +1 -1
  46. package/dist/brain/kg.js +3 -1
  47. package/dist/brain/kg.js.map +1 -1
  48. package/dist/build-metadata.json +1 -1
  49. package/dist/config.d.ts +7 -0
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +7 -2
  52. package/dist/config.js.map +1 -1
  53. package/dist/delegation/claude.d.ts +28 -0
  54. package/dist/delegation/claude.d.ts.map +1 -0
  55. package/dist/delegation/claude.js +107 -0
  56. package/dist/delegation/claude.js.map +1 -0
  57. package/dist/delegation/index.d.ts +2 -0
  58. package/dist/delegation/index.d.ts.map +1 -0
  59. package/dist/delegation/index.js +2 -0
  60. package/dist/delegation/index.js.map +1 -0
  61. package/dist/execution/attribution.d.ts +3 -0
  62. package/dist/execution/attribution.d.ts.map +1 -1
  63. package/dist/execution/attribution.js.map +1 -1
  64. package/dist/execution/delegated.d.ts.map +1 -1
  65. package/dist/execution/delegated.js +5 -2
  66. package/dist/execution/delegated.js.map +1 -1
  67. package/dist/execution/ledger-cli.d.ts.map +1 -1
  68. package/dist/execution/ledger-cli.js +9 -7
  69. package/dist/execution/ledger-cli.js.map +1 -1
  70. package/dist/execution/ledger-server.d.ts +6 -0
  71. package/dist/execution/ledger-server.d.ts.map +1 -1
  72. package/dist/execution/ledger-server.js +39 -4
  73. package/dist/execution/ledger-server.js.map +1 -1
  74. package/dist/execution/quote.d.ts +1 -1
  75. package/dist/execution/quote.d.ts.map +1 -1
  76. package/dist/execution/quote.js +4 -2
  77. package/dist/execution/quote.js.map +1 -1
  78. package/dist/execution/remote-ledger.d.ts +7 -0
  79. package/dist/execution/remote-ledger.d.ts.map +1 -1
  80. package/dist/execution/remote-ledger.js +22 -5
  81. package/dist/execution/remote-ledger.js.map +1 -1
  82. package/dist/health/target.d.ts.map +1 -1
  83. package/dist/health/target.js +8 -1
  84. package/dist/health/target.js.map +1 -1
  85. package/dist/improvement/cli.d.ts +1 -1
  86. package/dist/improvement/cli.d.ts.map +1 -1
  87. package/dist/improvement/cli.js +4 -4
  88. package/dist/improvement/cli.js.map +1 -1
  89. package/dist/improvement/host-capabilities.d.ts +134 -1
  90. package/dist/improvement/host-capabilities.d.ts.map +1 -1
  91. package/dist/improvement/host-capabilities.js +8 -1
  92. package/dist/improvement/host-capabilities.js.map +1 -1
  93. package/dist/improvement/index.d.ts +2 -0
  94. package/dist/improvement/index.d.ts.map +1 -1
  95. package/dist/improvement/index.js +2 -0
  96. package/dist/improvement/index.js.map +1 -1
  97. package/dist/improvement/task-feedback-contract.d.ts +41 -0
  98. package/dist/improvement/task-feedback-contract.d.ts.map +1 -0
  99. package/dist/improvement/task-feedback-contract.js +83 -0
  100. package/dist/improvement/task-feedback-contract.js.map +1 -0
  101. package/dist/improvement/task-feedback.d.ts +149 -0
  102. package/dist/improvement/task-feedback.d.ts.map +1 -0
  103. package/dist/improvement/task-feedback.js +117 -0
  104. package/dist/improvement/task-feedback.js.map +1 -0
  105. package/dist/improvement/task-outcomes.d.ts +2 -2
  106. package/dist/improvement/task-outcomes.d.ts.map +1 -1
  107. package/dist/improvement/task-outcomes.js +2 -3
  108. package/dist/improvement/task-outcomes.js.map +1 -1
  109. package/dist/model-detection.d.ts +0 -5
  110. package/dist/model-detection.d.ts.map +1 -1
  111. package/dist/model-detection.js +5 -5
  112. package/dist/model-detection.js.map +1 -1
  113. package/dist/orchestration/coordinator-types.d.ts +4 -1
  114. package/dist/orchestration/coordinator-types.d.ts.map +1 -1
  115. package/dist/orchestration/execution-journal.d.ts.map +1 -1
  116. package/dist/orchestration/execution-journal.js +10 -3
  117. package/dist/orchestration/execution-journal.js.map +1 -1
  118. package/dist/orchestration/execution.d.ts +3 -1
  119. package/dist/orchestration/execution.d.ts.map +1 -1
  120. package/dist/orchestration/execution.js +1 -1
  121. package/dist/orchestration/execution.js.map +1 -1
  122. package/dist/orchestration/reviewed-ledger.d.ts +42 -0
  123. package/dist/orchestration/reviewed-ledger.d.ts.map +1 -1
  124. package/dist/orchestration/reviewed-ledger.js +51 -9
  125. package/dist/orchestration/reviewed-ledger.js.map +1 -1
  126. package/dist/orchestration/routing.d.ts +2 -0
  127. package/dist/orchestration/routing.d.ts.map +1 -1
  128. package/dist/orchestration/routing.js +10 -1
  129. package/dist/orchestration/routing.js.map +1 -1
  130. package/dist/orchestration/task-configuration.d.ts +8 -0
  131. package/dist/orchestration/task-configuration.d.ts.map +1 -0
  132. package/dist/orchestration/task-configuration.js +23 -0
  133. package/dist/orchestration/task-configuration.js.map +1 -0
  134. package/dist/providers/chatgpt.d.ts +11 -0
  135. package/dist/providers/chatgpt.d.ts.map +1 -0
  136. package/dist/providers/chatgpt.js +156 -0
  137. package/dist/providers/chatgpt.js.map +1 -0
  138. package/dist/providers/index.d.ts +0 -5
  139. package/dist/providers/index.d.ts.map +1 -1
  140. package/dist/providers/index.js +10 -2
  141. package/dist/providers/index.js.map +1 -1
  142. package/dist/providers/types.d.ts +5 -0
  143. package/dist/providers/types.d.ts.map +1 -1
  144. package/dist/providers/types.js.map +1 -1
  145. package/dist/runlog.d.ts +1 -1
  146. package/dist/runlog.d.ts.map +1 -1
  147. package/dist/runtime/permissions.d.ts.map +1 -1
  148. package/dist/runtime/permissions.js +1 -0
  149. package/dist/runtime/permissions.js.map +1 -1
  150. package/dist/runtime/turn.d.ts.map +1 -1
  151. package/dist/runtime/turn.js +79 -12
  152. package/dist/runtime/turn.js.map +1 -1
  153. package/dist/sessions/execution-binding.d.ts +8 -3
  154. package/dist/sessions/execution-binding.d.ts.map +1 -1
  155. package/dist/sessions/execution-binding.js +13 -3
  156. package/dist/sessions/execution-binding.js.map +1 -1
  157. package/dist/types.d.ts +1 -0
  158. package/dist/types.d.ts.map +1 -1
  159. package/dist/types.js.map +1 -1
  160. package/dist/ui/components.d.ts.map +1 -1
  161. package/dist/ui/components.js +3 -5
  162. package/dist/ui/components.js.map +1 -1
  163. package/dist/ui/frame.js +3 -3
  164. package/dist/ui/frame.js.map +1 -1
  165. package/dist/ui/modals/tool-output.d.ts.map +1 -1
  166. package/dist/ui/modals/tool-output.js +5 -6
  167. package/dist/ui/modals/tool-output.js.map +1 -1
  168. package/dist/ui/state/use-terminal-width.d.ts.map +1 -1
  169. package/dist/ui/state/use-terminal-width.js +2 -13
  170. package/dist/ui/state/use-terminal-width.js.map +1 -1
  171. package/docs/chatgpt-plan.md +109 -0
  172. package/docs/claude-plan.md +58 -0
  173. package/docs/delegation-ledger.md +54 -3
  174. package/docs/improvement-cycles.md +5 -0
  175. package/docs/releases/3.8.0.md +65 -0
  176. package/docs/reviewed-provider-metadata.md +84 -0
  177. package/docs/task-feedback.md +77 -0
  178. package/package.json +17 -11
package/README.md CHANGED
@@ -125,10 +125,23 @@ One file, 16 keys. Credentials live in a per-provider map with environment-varia
125
125
 
126
126
  Docs: [getting started](docs/getting-started.md) · [commands](docs/commands.md) · [configuration](docs/configuration.md) · [model preferences](docs/model-preferences.md) · [providers](docs/providers.md) · [features](docs/features.md) · [fleet mode](docs/fleet.md)
127
127
 
128
+ ### ChatGPT plan access
129
+
130
+ Run `calliope auth chatgpt login` to select subscription-backed OpenAI access.
131
+ Use `calliope auth chatgpt status` to inspect accounts, and `api-key` to return to
132
+ Platform API billing. See [ChatGPT plan access](docs/chatgpt-plan.md) for account
133
+ management, output/budget restrictions and live-validation requirements.
134
+
128
135
  ## Editors
129
136
 
130
137
  Run Calliope as an [Agent Client Protocol](https://agentclientprotocol.com) agent (`calliope acp`) inside Zed, JetBrains, Neovim, and other ACP editors — client-side file edits, per-tool permissions, and the same audit trail. See [docs/acp.md](docs/acp.md).
131
138
 
139
+ ### Local Claude plan access
140
+
141
+ Run `calliope claude status`, then `calliope claude -- <prompt>` to delegate to your
142
+ installed, signed-in Claude agent. Claude owns permissions and plan usage in this
143
+ mode. See [local Claude delegation](docs/claude-plan.md).
144
+
132
145
  ## Fleet mode
133
146
 
134
147
  Coordinate a fleet of agents and human operators over a self-hosted IRC channel that doubles as an audit trail. Off by default, zero cost when disabled. See [docs/fleet.md](docs/fleet.md).
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/approvals/request.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,MAAM,SAAU,MAAM,KAAG,MAAyD,CAAC;AAChG,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAcpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAelD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAIpF;AACD,eAAO,MAAM,mBAAmB,UAAW,MAAM,WAAuK,CAAC;AAEzN,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CAoB7E"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/approvals/request.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,MAAM,SAAU,MAAM,KAAG,MAAyD,CAAC;AAChG,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAcpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAelD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAIpF;AACD,eAAO,MAAM,mBAAmB,UAAW,MAAM,WAAuK,CAAC;AAEzN,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CA4B7E"}
@@ -95,6 +95,16 @@ export function describeApproval(call, cwd) {
95
95
  details.push(`Operation: ${approvalDisplayText(call.arguments.operation)}`);
96
96
  if (typeof call.arguments.content === 'string')
97
97
  details.push(`Content: ${Buffer.byteLength(call.arguments.content)} bytes; SHA-256 ${digest(call.arguments.content)}`);
98
+ if (call.name === 'orchestration_budget' && call.arguments.providerTargets !== undefined) {
99
+ const targets = call.arguments.providerTargets;
100
+ if (!targets || typeof targets !== 'object' || Array.isArray(targets) || Object.keys(targets).length > 32)
101
+ throw new ApprovalError('invalid reviewed provider targets.');
102
+ for (const [provider, target] of Object.entries(targets).sort()) {
103
+ if (!/^[a-z][a-z0-9-]{0,63}$/.test(provider) || typeof target !== 'string' || !/^[a-f0-9]{64}$/.test(target))
104
+ throw new ApprovalError('invalid reviewed provider target.');
105
+ details.push(`Provider target: ${provider} SHA-256 ${target}`);
106
+ }
107
+ }
98
108
  details.push(`Arguments: SHA-256 ${digest(args)} (${Buffer.byteLength(args)} bytes)`);
99
109
  return { version: 1, ...{ project, projectKey }, key: digest(canonicalJson({ projectKey, tool: call.name, args, path: path ?? null, policy })),
100
110
  tool: call.name, risk: risk.level, reason: approvalDisplayText(risk.reason), details, reusable };
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/approvals/request.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/approvals/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { StreamProtocolError } from '../../errors.js';
2
+ import type { Message } from '../../types.js';
3
+ import { ChatGPTStore } from './store.js';
4
+ export declare const apiKeyAccessActive: () => boolean;
5
+ export declare const withAPIKeyAccess: <T>(action: () => T) => T;
6
+ export interface ChatGPTFallbackPolicy {
7
+ model: string;
8
+ maxProjectCostUsd: number;
9
+ maxOutputTokens: number;
10
+ cooldownSeconds: number;
11
+ }
12
+ export declare class ChatGPTQuotaError extends StreamProtocolError {
13
+ readonly reason: 'quota' | 'rate-limit';
14
+ readonly partial: boolean;
15
+ constructor(reason: 'quota' | 'rate-limit', partial?: boolean);
16
+ }
17
+ export declare function fallbackPolicy(): ChatGPTFallbackPolicy | undefined;
18
+ export declare function validateFallbackPolicy(p: ChatGPTFallbackPolicy): ChatGPTFallbackPolicy;
19
+ export declare function quotaCircuit(store?: ChatGPTStore, now?: number): {
20
+ reason: 'quota' | 'rate-limit';
21
+ until: number;
22
+ } | undefined;
23
+ export declare function openQuotaCircuit(clientId: string, reason: 'quota' | 'rate-limit', store?: ChatGPTStore): Promise<void>;
24
+ export declare function fallbackHistory(messages: Message[]): {
25
+ clientId: string;
26
+ model: string;
27
+ } | undefined;
28
+ /** Preserve visible conversation and completed tool pairs; never send encrypted plan state to an API key. */
29
+ export declare function publicFallbackHistory(messages: Message[], clientId: string, model: string): Message[];
30
+ export declare function runFallbackCommand(args: string[], signal?: AbortSignal): Promise<void>;
31
+ //# sourceMappingURL=fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/fallback.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,eAAO,MAAM,kBAAkB,eAAsC,CAAC;AACtE,eAAO,MAAM,gBAAgB,GAAI,CAAC,UAAU,MAAM,CAAC,KAAG,CAAgC,CAAC;AACvF,MAAM,WAAW,qBAAqB;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE;AACrI,qBAAa,iBAAkB,SAAQ,mBAAmB;IAC5C,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY;IAAE,QAAQ,CAAC,OAAO;IAArE,YAAqB,MAAM,EAAE,OAAO,GAAG,YAAY,EAAW,OAAO,UAAQ,EAG5E;CACF;AACD,wBAAgB,cAAc,IAAI,qBAAqB,GAAG,SAAS,CAGlE;AACD,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,qBAAqB,CAQtF;AACD,wBAAgB,YAAY,CAAC,KAAK,eAAqB,EAAE,GAAG,SAAa;;;cAGxE;AACD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,YAAY,EAAE,KAAK,eAAqB,iBAOlH;AACD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAWpG;AACD,6GAA6G;AAC7G,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAiBrG;AACD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB5F"}
@@ -0,0 +1,111 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import * as config from '../../config.js';
3
+ import { StreamProtocolError } from '../../errors.js';
4
+ import { ChatGPTStore } from './store.js';
5
+ import { ChatGPTAuthError } from './protocol.js';
6
+ const apiAccess = new AsyncLocalStorage();
7
+ export const apiKeyAccessActive = () => apiAccess.getStore() === true;
8
+ export const withAPIKeyAccess = (action) => apiAccess.run(true, action);
9
+ export class ChatGPTQuotaError extends StreamProtocolError {
10
+ reason;
11
+ partial;
12
+ constructor(reason, partial = false) {
13
+ super(reason === 'quota' ? 'ChatGPT plan usage limit reached. Subscription inference is paused; configure API-key fallback or wait for the cooldown.' : 'ChatGPT rate limit reached. Subscription inference is paused until the cooldown.');
14
+ this.reason = reason;
15
+ this.partial = partial;
16
+ this.name = 'ChatGPTQuotaError';
17
+ }
18
+ }
19
+ export function fallbackPolicy() {
20
+ const p = config.get('chatgptFallback');
21
+ return p == null ? undefined : validateFallbackPolicy(p);
22
+ }
23
+ export function validateFallbackPolicy(p) {
24
+ if (!p || typeof p.model !== 'string' || !p.model.trim() || p.model.length > 512 || /[\x00-\x20\x7f]/.test(p.model) ||
25
+ !Number.isFinite(p.maxProjectCostUsd) || p.maxProjectCostUsd <= 0 || p.maxProjectCostUsd > 1000000 ||
26
+ !Number.isSafeInteger(p.maxOutputTokens) || p.maxOutputTokens < 1 || p.maxOutputTokens > 100000000 ||
27
+ !Number.isSafeInteger(p.cooldownSeconds) || p.cooldownSeconds < 1 || p.cooldownSeconds > 86400 ||
28
+ Object.keys(p).some(k => !['model', 'maxProjectCostUsd', 'maxOutputTokens', 'cooldownSeconds'].includes(k)))
29
+ throw new ChatGPTAuthError('Invalid ChatGPT fallback configuration. Configure it again before using paid fallback.');
30
+ return { ...p };
31
+ }
32
+ export function quotaCircuit(store = new ChatGPTStore(), now = Date.now()) {
33
+ const breaker = store.active()?.quotaCircuit;
34
+ return breaker && breaker.until > now ? { ...breaker } : undefined;
35
+ }
36
+ export async function openQuotaCircuit(clientId, reason, store = new ChatGPTStore()) {
37
+ const configured = config.get('chatgptFallback')?.cooldownSeconds;
38
+ const seconds = reason === 'rate-limit' ? 60 : Number.isSafeInteger(configured) && configured >= 1 && configured <= 86400 ? configured : 3600;
39
+ await store.update(state => {
40
+ const a = state.accounts[clientId];
41
+ if (a)
42
+ a.quotaCircuit = { reason, until: Date.now() + seconds * 1000 };
43
+ });
44
+ }
45
+ export function fallbackHistory(messages) {
46
+ let found;
47
+ for (const m of messages) {
48
+ const marker = m.providerMetadata?.openai?.chatgptFallback;
49
+ if (!marker)
50
+ continue;
51
+ if (!/^oaiapp_[\w-]+$/.test(marker.clientId) || typeof marker.model !== 'string' || !marker.model ||
52
+ found && (found.clientId !== marker.clientId || found.model !== marker.model))
53
+ throw new ChatGPTAuthError('Inconsistent API-key fallback history. Start a new session.');
54
+ found = { clientId: marker.clientId, model: marker.model };
55
+ }
56
+ return found;
57
+ }
58
+ /** Preserve visible conversation and completed tool pairs; never send encrypted plan state to an API key. */
59
+ export function publicFallbackHistory(messages, clientId, model) {
60
+ const existing = fallbackHistory(messages);
61
+ if (existing && (existing.clientId !== clientId || existing.model !== model))
62
+ throw new ChatGPTAuthError('Fallback account or model changed. Start a new session.');
63
+ const result = messages.map(m => {
64
+ const metadata = m.providerMetadata;
65
+ if (metadata && Object.keys(metadata).some(k => k !== 'openai' && k !== 'calliopeRouting'))
66
+ throw new ChatGPTAuthError('Other provider state cannot be converted to API-key fallback. Start a new session.');
67
+ if (metadata?.openai && Object.keys(metadata.openai).some(k => k !== 'chatgpt' && k !== 'chatgptFallback'))
68
+ throw new ChatGPTAuthError('Unknown OpenAI state cannot be converted to API-key fallback. Start a new session.');
69
+ const saved = metadata?.openai?.chatgpt;
70
+ if (saved && saved.clientId !== clientId)
71
+ throw new ChatGPTAuthError('ChatGPT history belongs to a different account. Start a new session.');
72
+ const { providerMetadata: _opaque, ...publicMessage } = m;
73
+ return structuredClone(publicMessage);
74
+ });
75
+ const last = result.at(-1);
76
+ if (last)
77
+ last.providerMetadata = { openai: { chatgptFallback: { clientId, model } }, calliopeRouting: { provider: 'openai', model } };
78
+ return result;
79
+ }
80
+ export async function runFallbackCommand(args, signal) {
81
+ const store = new ChatGPTStore();
82
+ if (args.length === 1 && args[0] === 'models') {
83
+ if (!config.getApiKey('openai'))
84
+ throw new ChatGPTAuthError('Configure an OpenAI API key before listing paid fallback models.');
85
+ const { getAvailableModels } = await import('../../model-detection.js');
86
+ const { providerTarget } = await import('../../health/index.js');
87
+ const result = await withAPIKeyAccess(async () => ({ target: providerTarget('openai').key, models: await getAvailableModels('openai', { signal, quiet: true, throwOnError: true }) }));
88
+ console.log(JSON.stringify(result, null, 2));
89
+ }
90
+ else if (args[0] === 'enable' && (args.length === 3 || args.length === 4)) {
91
+ if (!config.getApiKey('openai'))
92
+ throw new ChatGPTAuthError('Configure an OpenAI API key before enabling paid fallback.');
93
+ config.set('chatgptFallback', validateFallbackPolicy({ model: args[1], maxProjectCostUsd: Number(args[2]), maxOutputTokens: Number(args[3] ?? 4096), cooldownSeconds: 3600 }));
94
+ console.log('Paid OpenAI API-key fallback enabled. Each request requires live model discovery, verified billing bounds and a shared project-budget reservation. Existing project spend counts toward this cap.');
95
+ }
96
+ else if (args.length === 1 && args[0] === 'disable') {
97
+ config.set('chatgptFallback', null);
98
+ console.log('Automatic paid fallback disabled.');
99
+ }
100
+ else if (args.length === 1 && args[0] === 'reset') {
101
+ await store.update(s => { if (s.active)
102
+ delete s.accounts[s.active].quotaCircuit; });
103
+ console.log('Subscription quota circuit reset. Existing API-key fallback sessions stay on the paid route; start a new session to try the plan again.');
104
+ }
105
+ else if (args.length === 1 && args[0] === 'status') {
106
+ console.log(JSON.stringify({ enabled: !!fallbackPolicy(), policy: fallbackPolicy() ?? null, circuit: quotaCircuit(store) ?? null }, null, 2));
107
+ }
108
+ else
109
+ throw new ChatGPTAuthError('Usage: calliope auth chatgpt fallback enable <api-model> <max-project-cost-usd> [max-output-tokens] | models | disable | status | reset');
110
+ }
111
+ //# sourceMappingURL=fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/fallback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './protocol.js';
2
+ export * from './store.js';
3
+ export * from './session.js';
4
+ export * from './login.js';
5
+ export * from './fallback.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './protocol.js';
2
+ export * from './store.js';
3
+ export * from './session.js';
4
+ export * from './login.js';
5
+ export * from './fallback.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ChatGPTStore } from './store.js';
2
+ export declare function openBrowser(url: string): Promise<void>;
3
+ export declare function login(store?: ChatGPTStore, clientId?: string, signal?: AbortSignal, launch?: typeof openBrowser): Promise<void>;
4
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/login.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAStD;AACD,wBAAsB,KAAK,CAAC,KAAK,eAAqB,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,qBAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CpI"}
@@ -0,0 +1,82 @@
1
+ import { createServer } from 'node:http';
2
+ import { spawn } from 'node:child_process';
3
+ import { ChatGPTStore } from './store.js';
4
+ import { prepareAuthorization, ChatGPTAuthError } from './protocol.js';
5
+ import { tokenRequest, validateIdentity, applyTokens } from './session.js';
6
+ export function openBrowser(url) {
7
+ // argv only; no shell and no user-controlled executable.
8
+ const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'rundll32.exe' : 'xdg-open';
9
+ const args = process.platform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
10
+ return new Promise((resolve, reject) => {
11
+ const child = spawn(command, args, { stdio: 'ignore', shell: false });
12
+ child.once('error', () => reject(new ChatGPTAuthError('Could not open the browser.')));
13
+ child.once('exit', code => code === 0 ? resolve() : reject(new ChatGPTAuthError('Could not open the browser.')));
14
+ });
15
+ }
16
+ export async function login(store = new ChatGPTStore(), clientId, signal, launch = openBrowser) {
17
+ // Persist host identity before opening a browser; failed attempts retain it.
18
+ await store.update(() => { });
19
+ const state = store.read();
20
+ const previous = clientId ? state.accounts[clientId] : undefined;
21
+ if (clientId && !previous)
22
+ throw new ChatGPTAuthError('Unknown ChatGPT registration. Use auth chatgpt status.');
23
+ const server = createServer();
24
+ await new Promise((resolve, reject) => { server.once('error', reject); server.listen(0, '127.0.0.1', resolve); });
25
+ const address = server.address();
26
+ if (!address || typeof address === 'string')
27
+ throw new ChatGPTAuthError('Could not start ChatGPT callback listener.');
28
+ const redirect = `http://127.0.0.1:${address.port}/auth/callback`;
29
+ const attempt = prepareAuthorization(state.hostId, redirect, previous);
30
+ let timer;
31
+ let abort;
32
+ try {
33
+ const callback = new Promise((resolve, reject) => {
34
+ timer = setTimeout(() => reject(new ChatGPTAuthError('ChatGPT sign-in timed out.')), 300000);
35
+ abort = () => reject(new ChatGPTAuthError('ChatGPT sign-in cancelled.'));
36
+ signal?.addEventListener('abort', abort, { once: true });
37
+ if (signal?.aborted) {
38
+ abort();
39
+ return;
40
+ }
41
+ server.on('request', (req, res) => {
42
+ res.setHeader('Cache-Control', 'no-store');
43
+ res.setHeader('Content-Type', 'text/plain');
44
+ if (req.method !== 'GET' || req.headers.host !== `127.0.0.1:${address.port}` || !req.url?.startsWith('/auth/callback?')) {
45
+ res.writeHead(404).end('Not found');
46
+ return;
47
+ }
48
+ try {
49
+ const result = attempt.consume(new URL(req.url, redirect).href);
50
+ res.end('Authorization received. Return to your terminal to finish verification.');
51
+ resolve(result);
52
+ }
53
+ catch (e) {
54
+ res.writeHead(400).end('Sign-in rejected. Return to your terminal.');
55
+ reject(e);
56
+ }
57
+ });
58
+ });
59
+ // Attach a rejection handler before browser launch so an immediate abort is handled.
60
+ const [result] = await Promise.all([callback, launch(attempt.url)]);
61
+ const tokens = await tokenRequest(result.form, signal);
62
+ if (!tokens.id_token)
63
+ throw new ChatGPTAuthError('ChatGPT did not return an identity token.');
64
+ const identity = await validateIdentity(tokens.id_token, result.clientId, attempt.nonce, previous ?? state.accounts[result.clientId]);
65
+ signal?.throwIfAborted();
66
+ await store.update(current => {
67
+ if (JSON.stringify(current.accounts[result.clientId]) !== JSON.stringify(state.accounts[result.clientId]))
68
+ throw new ChatGPTAuthError('ChatGPT registration changed during sign-in. Retry.');
69
+ current.accounts[result.clientId] = applyTokens({ clientId: result.clientId, ...identity, scopes: [] }, tokens);
70
+ current.active = result.clientId;
71
+ });
72
+ }
73
+ finally {
74
+ attempt.cancel();
75
+ clearTimeout(timer);
76
+ if (abort)
77
+ signal?.removeEventListener('abort', abort);
78
+ server.closeAllConnections();
79
+ await new Promise(resolve => server.close(() => resolve()));
80
+ }
81
+ }
82
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export declare const ISSUER = "https://auth.openai.com";
2
+ export declare const RESOURCE = "https://api.openai.com/v1";
3
+ export declare const TOKEN_URL = "https://auth.openai.com/api/accounts/oauth/token";
4
+ export declare const SCOPES = "openid profile email offline_access resource.invoke chatgpt.tokens.use.direct";
5
+ export declare class ChatGPTAuthError extends Error {
6
+ readonly code?: 'reauthenticate' | undefined;
7
+ constructor(message: string, code?: 'reauthenticate' | undefined);
8
+ }
9
+ export interface Registration {
10
+ clientId: string;
11
+ subject: string;
12
+ email?: string;
13
+ idToken?: string;
14
+ }
15
+ export declare function prepareAuthorization(hostId: string, redirectUri: string, registration?: Registration, now?: number): {
16
+ url: string;
17
+ nonce: string;
18
+ cancel(): void;
19
+ consume(callback: string, at?: number): {
20
+ clientId: string;
21
+ form: import("node:url").URLSearchParams;
22
+ };
23
+ };
24
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/protocol.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,MAAM,4BAA4B,CAAC;AAChD,eAAO,MAAM,QAAQ,8BAA8B,CAAC;AACpD,eAAO,MAAM,SAAS,qDAAuC,CAAC;AAC9D,eAAO,MAAM,MAAM,kFAAkF,CAAC;AACtG,qBAAa,gBAAiB,SAAQ,KAAK;IAAgC,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB;IAA7D,YAAY,OAAO,EAAE,MAAM,EAAW,IAAI,CAAC,EAAE,gBAAgB,YAAA,EAAqD;CAAE;AAElK,MAAM,WAAW,YAAY;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AACrG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,GAAG,SAAa;;;;sBAejG,MAAM;;;;EAiB3B"}
@@ -0,0 +1,71 @@
1
+ import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
2
+ export const ISSUER = 'https://auth.openai.com';
3
+ export const RESOURCE = 'https://api.openai.com/v1';
4
+ export const TOKEN_URL = `${ISSUER}/api/accounts/oauth/token`;
5
+ export const SCOPES = 'openid profile email offline_access resource.invoke chatgpt.tokens.use.direct';
6
+ export class ChatGPTAuthError extends Error {
7
+ code;
8
+ constructor(message, code) {
9
+ super(message);
10
+ this.code = code;
11
+ this.name = 'ChatGPTAuthError';
12
+ }
13
+ }
14
+ const fail = () => new ChatGPTAuthError('ChatGPT callback rejected. Start a new sign-in.');
15
+ export function prepareAuthorization(hostId, redirectUri, registration, now = Date.now()) {
16
+ const uri = new URL(redirectUri);
17
+ if (uri.protocol !== 'http:' || uri.hostname !== '127.0.0.1' || uri.pathname !== '/auth/callback' || !uri.port || uri.search || uri.hash || uri.username || uri.password)
18
+ throw fail();
19
+ if (!/^urn:uuid:[0-9a-f-]{36}$/i.test(hostId))
20
+ throw new ChatGPTAuthError('Invalid ChatGPT host identity.');
21
+ if (registration && !/^oaiapp_[A-Za-z0-9_-]+$/.test(registration.clientId))
22
+ throw fail();
23
+ const state = randomBytes(32).toString('base64url'), nonce = randomBytes(32).toString('base64url'), verifier = randomBytes(32).toString('base64url');
24
+ const params = new URLSearchParams({ client_id: registration?.clientId ?? 'dynamic_agent_client', ext_agent_host_id: hostId,
25
+ response_type: 'code', redirect_uri: redirectUri, scope: SCOPES, resource: RESOURCE, state, nonce,
26
+ code_challenge_method: 'S256', code_challenge: createHash('sha256').update(verifier).digest('base64url') });
27
+ if (!registration)
28
+ params.set('agent_name_hint', 'Calliope AI CLI');
29
+ else {
30
+ if (registration.idToken)
31
+ params.set('id_token_hint', registration.idToken);
32
+ if (registration.email)
33
+ params.set('login_hint', registration.email);
34
+ }
35
+ let consumed = false;
36
+ return {
37
+ url: `${ISSUER}/api/accounts/authorize?${params}`, nonce,
38
+ cancel() { consumed = true; },
39
+ consume(callback, at = Date.now()) {
40
+ if (consumed)
41
+ throw fail();
42
+ consumed = true;
43
+ if (at < now || at - now > 300000)
44
+ throw fail();
45
+ let url;
46
+ try {
47
+ url = new URL(callback);
48
+ }
49
+ catch {
50
+ throw fail();
51
+ }
52
+ if (url.origin !== uri.origin || url.pathname !== uri.pathname || url.hash || url.username || url.password)
53
+ throw fail();
54
+ for (const key of url.searchParams.keys())
55
+ if (url.searchParams.getAll(key).length !== 1)
56
+ throw fail();
57
+ const received = Buffer.from(url.searchParams.get('state') ?? '');
58
+ if (received.length !== state.length || !timingSafeEqual(received, Buffer.from(state)))
59
+ throw fail();
60
+ if (url.searchParams.has('error'))
61
+ throw new ChatGPTAuthError('ChatGPT sign-in was denied or failed.');
62
+ const clientId = url.searchParams.get('client_id') ?? registration?.clientId;
63
+ const code = url.searchParams.get('code');
64
+ if (!code || !clientId || !/^oaiapp_[A-Za-z0-9_-]+$/.test(clientId) || registration && clientId !== registration.clientId)
65
+ throw fail();
66
+ return { clientId, form: new URLSearchParams({ grant_type: 'authorization_code', client_id: clientId, code,
67
+ code_verifier: verifier, redirect_uri: redirectUri, resource: RESOURCE }) };
68
+ },
69
+ };
70
+ }
71
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type JWTVerifyGetKey } from 'jose';
2
+ import { ChatGPTStore, type Account } from './store.js';
3
+ import { type Registration } from './protocol.js';
4
+ export interface Tokens {
5
+ access_token: string;
6
+ refresh_token: string;
7
+ id_token?: string;
8
+ token_type: string;
9
+ expires_in: number;
10
+ scope: string;
11
+ earliest_refresh_at?: number;
12
+ }
13
+ export declare function tokenRequest(form: URLSearchParams, signal?: AbortSignal): Promise<Tokens>;
14
+ export declare function validateIdentity(token: string, clientId: string, nonce?: string, previous?: Registration, key?: JWTVerifyGetKey): Promise<{
15
+ subject: string;
16
+ email?: string | undefined;
17
+ }>;
18
+ export declare function applyTokens(account: Account, tokens: Tokens): Account;
19
+ export declare function accessToken(store?: ChatGPTStore, signal?: AbortSignal): Promise<{
20
+ token: string;
21
+ clientId: string;
22
+ }>;
23
+ export declare function logout(store?: ChatGPTStore): Promise<boolean>;
24
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,eAAe,EAAE,MAAM,MAAM,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAiD,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjG,MAAM,WAAW,MAAM;IAAG,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE;AAC/K,wBAAsB,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAW/F;AACD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,GAAE,eAAsB;;;GAM3I;AACD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIrE;AACD,wBAAsB,WAAW,CAAC,KAAK,eAAqB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBhI;AACD,wBAAsB,MAAM,CAAC,KAAK,eAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBzE"}
@@ -0,0 +1,101 @@
1
+ import { createRemoteJWKSet, jwtVerify } from 'jose';
2
+ import { ChatGPTStore } from './store.js';
3
+ import { ChatGPTAuthError, ISSUER, TOKEN_URL, RESOURCE } from './protocol.js';
4
+ const jwks = createRemoteJWKSet(new URL(`${ISSUER}/.well-known/jwks.json`));
5
+ export async function tokenRequest(form, signal) {
6
+ let response;
7
+ try {
8
+ response = await fetch(TOKEN_URL, { method: 'POST', redirect: 'error', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: form, signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(30000)]) : AbortSignal.timeout(30000) });
9
+ }
10
+ catch {
11
+ throw new ChatGPTAuthError('ChatGPT token request failed. Retry sign-in or check your connection.');
12
+ }
13
+ let body;
14
+ try {
15
+ body = await response.json();
16
+ }
17
+ catch {
18
+ throw new ChatGPTAuthError('Invalid ChatGPT token response.');
19
+ }
20
+ if (!response.ok) {
21
+ const terminal = ['invalid_grant', 'invalid_refresh_token', 'token_expired', 'refresh_token_expired', 'refresh_token_invalidated', 'refresh_token_reused'].includes(String(body.error));
22
+ throw new ChatGPTAuthError(terminal ? 'ChatGPT session expired or revoked. Sign in again.' : `ChatGPT token request failed (HTTP ${response.status}).`, terminal ? 'reauthenticate' : undefined);
23
+ }
24
+ if (typeof body.access_token !== 'string' || !body.access_token || typeof body.refresh_token !== 'string' || !body.refresh_token || body.token_type !== 'Bearer' || typeof body.expires_in !== 'number' || !Number.isFinite(body.expires_in) || body.expires_in <= 0 || typeof body.scope !== 'string')
25
+ throw new ChatGPTAuthError('Invalid ChatGPT token response.');
26
+ return body;
27
+ }
28
+ export async function validateIdentity(token, clientId, nonce, previous, key = jwks) {
29
+ try {
30
+ const { payload } = await jwtVerify(token, key, { issuer: ISSUER, audience: clientId, algorithms: ['RS256'], requiredClaims: ['exp', 'iat', 'sub'] });
31
+ if (!payload.sub || nonce !== undefined && payload.nonce !== nonce || previous && payload.sub !== previous.subject)
32
+ throw Error();
33
+ return { subject: payload.sub, ...(typeof payload.email === 'string' ? { email: payload.email } : {}) };
34
+ }
35
+ catch {
36
+ throw new ChatGPTAuthError('ChatGPT identity verification failed. Sign in again.');
37
+ }
38
+ }
39
+ export function applyTokens(account, tokens) {
40
+ return { ...account, accessToken: tokens.access_token, refreshToken: tokens.refresh_token,
41
+ ...(tokens.id_token ? { idToken: tokens.id_token } : {}), scopes: tokens.scope.split(/\s+/).filter(Boolean),
42
+ expiresAt: Date.now() + tokens.expires_in * 1000, earliestRefreshAt: tokens.earliest_refresh_at ? tokens.earliest_refresh_at * 1000 : undefined };
43
+ }
44
+ export async function accessToken(store = new ChatGPTStore(), signal) {
45
+ const selected = store.active();
46
+ if (!selected?.accessToken || !selected.refreshToken || !selected.scopes.includes('chatgpt.tokens.use.direct'))
47
+ throw new ChatGPTAuthError('ChatGPT plan access is unavailable. Run calliope auth chatgpt login.');
48
+ if ((selected.expiresAt ?? 0) > Date.now() + 60000)
49
+ return { token: selected.accessToken, clientId: selected.clientId };
50
+ const result = await store.update(async (state) => {
51
+ if (state.active !== selected.clientId)
52
+ throw new ChatGPTAuthError('ChatGPT account changed. Retry the request.');
53
+ const a = state.accounts[selected.clientId];
54
+ if ((a.expiresAt ?? 0) > Date.now() + 60000)
55
+ return { token: a.accessToken, clientId: a.clientId };
56
+ if (a.earliestRefreshAt && a.earliestRefreshAt > Date.now())
57
+ throw new ChatGPTAuthError('ChatGPT token cannot refresh yet. Retry later.');
58
+ let tokens;
59
+ try {
60
+ tokens = await tokenRequest(new URLSearchParams({ grant_type: 'refresh_token', client_id: a.clientId, refresh_token: a.refreshToken, resource: RESOURCE }), signal);
61
+ }
62
+ catch (error) {
63
+ if (!(error instanceof ChatGPTAuthError) || error.code !== 'reauthenticate')
64
+ throw error;
65
+ state.accounts[a.clientId] = { clientId: a.clientId, subject: a.subject, email: a.email, scopes: [] };
66
+ return { error };
67
+ }
68
+ if (tokens.id_token)
69
+ await validateIdentity(tokens.id_token, a.clientId, undefined, a);
70
+ state.accounts[a.clientId] = applyTokens(a, tokens);
71
+ if (!state.accounts[a.clientId].scopes.includes('chatgpt.tokens.use.direct'))
72
+ return { error: new ChatGPTAuthError('ChatGPT plan permission was removed. Sign in again.') };
73
+ return { token: tokens.access_token, clientId: a.clientId };
74
+ });
75
+ if ('error' in result)
76
+ throw result.error;
77
+ return result;
78
+ }
79
+ export async function logout(store = new ChatGPTStore()) {
80
+ return store.update(async (state) => {
81
+ const a = state.active ? state.accounts[state.active] : undefined;
82
+ if (!a)
83
+ return true;
84
+ let revoked = !a.refreshToken;
85
+ if (a.refreshToken) {
86
+ try {
87
+ const discovery = await fetch(`${ISSUER}/.well-known/openid-configuration`, { redirect: 'error', signal: AbortSignal.timeout(10000) });
88
+ const metadata = await discovery.json();
89
+ const endpoint = new URL(metadata.revocation_endpoint);
90
+ if (!discovery.ok || metadata.issuer !== ISSUER || endpoint.origin !== ISSUER || endpoint.username || endpoint.password)
91
+ throw Error();
92
+ const response = await fetch(endpoint, { method: 'POST', redirect: 'error', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ token: a.refreshToken, token_type_hint: 'refresh_token', client_id: a.clientId }), signal: AbortSignal.timeout(10000) });
93
+ revoked = response.ok;
94
+ }
95
+ catch { /* Local sign-out still removes every token. */ }
96
+ }
97
+ state.accounts[a.clientId] = { clientId: a.clientId, subject: a.subject, email: a.email, scopes: [] };
98
+ return revoked;
99
+ });
100
+ }
101
+ //# sourceMappingURL=session.js.map