@modelprofile.com/authswitch 9.1.0 → 10.0.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 (75) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/authority-contract.d.ts +56 -6
  3. package/dist_ts/authority-contract.js +1 -1
  4. package/dist_ts/authority-runtime-contract.d.ts +29 -0
  5. package/dist_ts/classes.authoritybroker.d.ts +36 -4
  6. package/dist_ts/classes.authoritybroker.js +71 -12
  7. package/dist_ts/classes.authoritycli.d.ts +4 -1
  8. package/dist_ts/classes.authoritycli.js +42 -7
  9. package/dist_ts/classes.authorityclient.d.ts +15 -2
  10. package/dist_ts/classes.authorityclient.js +31 -8
  11. package/dist_ts/classes.authoritydaemon.d.ts +17 -0
  12. package/dist_ts/classes.authoritydaemon.js +50 -14
  13. package/dist_ts/classes.authoritydatabase.d.ts +14 -3
  14. package/dist_ts/classes.authoritydatabase.js +25 -10
  15. package/dist_ts/classes.authorityimport.d.ts +4 -4
  16. package/dist_ts/classes.authorityimport.js +8 -7
  17. package/dist_ts/classes.authoritymodels.d.ts +11 -3
  18. package/dist_ts/classes.authoritymodels.js +43 -13
  19. package/dist_ts/classes.authoritypreuse.d.ts +8 -2
  20. package/dist_ts/classes.authoritypreuse.js +27 -17
  21. package/dist_ts/classes.authorityusage.d.ts +4 -3
  22. package/dist_ts/classes.authorityusage.js +3 -5
  23. package/dist_ts/classes.cli.js +3 -5
  24. package/dist_ts/classes.codexpreuse.d.ts +14 -3
  25. package/dist_ts/classes.codexpreuse.js +127 -44
  26. package/dist_ts/classes.codexstatus.js +44 -95
  27. package/dist_ts/classes.login.d.ts +20 -10
  28. package/dist_ts/classes.login.js +14 -13
  29. package/dist_ts/classes.openaiprovider.d.ts +53 -0
  30. package/dist_ts/classes.openaiprovider.js +340 -0
  31. package/dist_ts/classes.opencodeharness.js +3 -2
  32. package/dist_ts/classes.service.js +3 -5
  33. package/dist_ts/index.d.ts +2 -0
  34. package/dist_ts/index.js +3 -1
  35. package/dist_ts/interfaces.openai.d.ts +118 -0
  36. package/dist_ts/interfaces.openai.js +3 -0
  37. package/dist_ts/openaiauth.d.ts +76 -0
  38. package/dist_ts/openaiauth.js +371 -0
  39. package/dist_ts/openaiusage.d.ts +59 -0
  40. package/dist_ts/openaiusage.js +222 -0
  41. package/dist_ts/plugins.d.ts +1 -3
  42. package/dist_ts/plugins.js +2 -4
  43. package/dist_ts/preuse.d.ts +50 -0
  44. package/dist_ts/preuse.js +63 -4
  45. package/dist_ts/ts_migration/legacysources/shared.js +4 -3
  46. package/openai-codex-license.txt +201 -0
  47. package/package.json +6 -4
  48. package/readme.md +121 -26
  49. package/third-party-notices.md +29 -0
  50. package/ts/00_commitinfo_data.ts +1 -1
  51. package/ts/authority-contract.ts +60 -8
  52. package/ts/authority-runtime-contract.ts +30 -0
  53. package/ts/classes.authoritybroker.ts +80 -17
  54. package/ts/classes.authoritycli.ts +48 -6
  55. package/ts/classes.authorityclient.ts +32 -9
  56. package/ts/classes.authoritydaemon.ts +54 -14
  57. package/ts/classes.authoritydatabase.ts +28 -11
  58. package/ts/classes.authorityimport.ts +12 -12
  59. package/ts/classes.authoritymodels.ts +42 -14
  60. package/ts/classes.authoritypreuse.ts +30 -17
  61. package/ts/classes.authorityusage.ts +8 -9
  62. package/ts/classes.cli.ts +3 -3
  63. package/ts/classes.codexpreuse.ts +130 -40
  64. package/ts/classes.codexstatus.ts +40 -73
  65. package/ts/classes.login.ts +34 -21
  66. package/ts/classes.openaiprovider.ts +365 -0
  67. package/ts/classes.opencodeharness.ts +3 -2
  68. package/ts/classes.service.ts +3 -4
  69. package/ts/index.ts +2 -0
  70. package/ts/interfaces.openai.ts +142 -0
  71. package/ts/openaiauth.ts +422 -0
  72. package/ts/openaiusage.ts +247 -0
  73. package/ts/plugins.ts +1 -3
  74. package/ts/preuse.ts +88 -3
  75. package/ts/ts_migration/legacysources/shared.ts +4 -3
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/authswitch',
6
- version: '9.1.0',
6
+ version: '10.0.0',
7
7
  description: 'Manage Codex, OpenCode and Claude Code accounts with guided switching and live usage status'
8
8
  };
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSw4QkFBOEI7SUFDcEMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDZGQUE2RjtDQUMzRyxDQUFBIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSw4QkFBOEI7SUFDcEMsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLDZGQUE2RjtDQUMzRyxDQUFBIn0=
@@ -124,6 +124,10 @@ export interface IAuthSwitchBinding {
124
124
  runtime: 'flex' | 'codex' | 'opencode' | 'claude';
125
125
  scopeId: string;
126
126
  incarnationId: string;
127
+ /**
128
+ * The authority revision at which this runtime and scope were last bound. It grows with every bind and never
129
+ * repeats for them, not even after a release and a new bind, so it names exactly one bind.
130
+ */
127
131
  revision: number;
128
132
  }
129
133
  /**
@@ -286,13 +290,11 @@ export interface IAuthSwitchAccountEvent {
286
290
  kind: 'account' | 'binding';
287
291
  accountId: string;
288
292
  }
293
+ /** What a device sign-in shows the person signing in; the authority signs in with a device code only. */
289
294
  export type TAuthSwitchLoginPrompt = {
290
295
  flow: 'device';
291
296
  verificationUrl: string;
292
297
  userCode: string;
293
- } | {
294
- flow: 'browser';
295
- authUrl: string;
296
298
  };
297
299
  export interface IAuthSwitchOperation {
298
300
  id: string;
@@ -314,7 +316,36 @@ export interface IAuthSwitchOperation {
314
316
  finishedAt: string | null;
315
317
  revision: number;
316
318
  }
317
- /** Credential-free receipt for one exact, never-replayed quota-consuming request. */
319
+ /**
320
+ * A limit that kept a preuse prompt from being answered: `usage_limit` is the account's quota, spent until it
321
+ * resets, `rate_limit` a short throttle. `window` names the window by its length (`weekly`, `five-hour`) and
322
+ * `resetsAt` is an ISO time; either is null when neither the usage reading nor the provider stated it.
323
+ */
324
+ export interface IAuthSwitchPreuseLimit {
325
+ kind: 'usage_limit' | 'rate_limit';
326
+ window: string | null;
327
+ resetsAt: string | null;
328
+ }
329
+ /**
330
+ * Why a sent preuse prompt failed without a limit, never with the provider's text. `http` is an answer with an
331
+ * HTTP error status; `stream` an error the answer stream reported after it began, with the
332
+ * machine-readable code the error states and no status, since its answer was a success; `response` an answer that could not be read; `network` a connection
333
+ * that failed before any answer; `aborted` an abort that was neither a cancellation nor the deadline; `unknown`
334
+ * anything else. `status` and `providerCode` are null when the failure did not state them.
335
+ */
336
+ export interface IAuthSwitchPreuseFailure {
337
+ kind: 'http' | 'stream' | 'response' | 'network' | 'aborted' | 'unknown';
338
+ status: number | null;
339
+ providerCode: string | null;
340
+ }
341
+ /**
342
+ * Credential-free receipt for one exact, never-replayed quota-consuming request.
343
+ *
344
+ * `not_sent` with `usage_limit` is an account whose own usage reading showed a reached limit, so nothing was
345
+ * sent; `refused` is a prompt the provider refused with a limit before it began to answer, so nothing was
346
+ * consumed. `limit` describes the limit whenever `problem` is `usage_limit` or `rate_limit`, and is null otherwise.
347
+ * `failure` names the cause of a `request_uncertain` request when it failed with one, and is null otherwise.
348
+ */
318
349
  export interface IAuthSwitchPreuseOperation {
319
350
  id: string;
320
351
  accountId: string;
@@ -322,13 +353,15 @@ export interface IAuthSwitchPreuseOperation {
322
353
  purpose: 'openai_managed';
323
354
  requestedModel: string | null;
324
355
  model: string | null;
325
- state: 'preparing' | 'request_may_have_started' | 'complete' | 'not_sent' | 'outcome_unknown';
356
+ state: 'preparing' | 'request_may_have_started' | 'complete' | 'not_sent' | 'refused' | 'outcome_unknown';
326
357
  result: {
327
358
  inputTokens: number | null;
328
359
  outputTokens: number | null;
329
360
  totalTokens: number | null;
330
361
  } | null;
331
- problem: 'none' | 'target_unavailable' | 'access_unavailable' | 'catalog_unavailable' | 'account_busy' | 'cancelled' | 'authority_closing' | 'interrupted' | 'request_uncertain';
362
+ problem: 'none' | 'target_unavailable' | 'access_unavailable' | 'catalog_unavailable' | 'account_busy' | 'cancelled' | 'authority_closing' | 'interrupted' | 'request_uncertain' | 'usage_limit' | 'rate_limit';
363
+ limit: IAuthSwitchPreuseLimit | null;
364
+ failure: IAuthSwitchPreuseFailure | null;
332
365
  createdAt: string;
333
366
  updatedAt: string;
334
367
  finishedAt: string | null;
@@ -562,14 +595,31 @@ export interface IReq_AuthSwitchGetBinding extends ITypedRequest {
562
595
  binding: IAuthSwitchBinding | null;
563
596
  };
564
597
  }
598
+ /**
599
+ * What a removal did about the account's ChatGPT sign-in at OpenAI:
600
+ * - `not_requested`: the caller did not ask; nothing reached the network.
601
+ * - `yes`: OpenAI confirmed the revocation.
602
+ * - `failed`: OpenAI did not confirm it, or not within the 10 seconds a removal's revocations are given in all;
603
+ * the sign-in may still be valid there. The account is removed anyway.
604
+ * - `not_applicable`: the authority held no ChatGPT sign-in of its own for the account.
605
+ */
606
+ export type TAuthSwitchRevocation = 'not_requested' | 'yes' | 'failed' | 'not_applicable';
607
+ /**
608
+ * Removes an account. With `revoke: true` the authority also revokes, after the removal committed, the ChatGPT
609
+ * sign-in it held for the account, and `revoked` says whether OpenAI confirmed it. The revocations take at most 10
610
+ * seconds in all, so a revoking removal answers within a request's usual 35 seconds. A revocation is irreversible
611
+ * and reaches everything that still refreshes from that sign-in, which the authority cannot see: see the readme.
612
+ */
565
613
  export interface IReq_AuthSwitchRemoveAccount extends ITypedRequest {
566
614
  method: 'authswitch.authority.remove';
567
615
  request: {
568
616
  accountId: string;
569
617
  expectedRevision: number;
618
+ revoke?: true;
570
619
  };
571
620
  response: {
572
621
  account: IAuthSwitchAccount;
622
+ revoked: TAuthSwitchRevocation;
573
623
  };
574
624
  }
575
625
  /** Runtime capability is returned only to trusted backend callers; do not expose this response in a browser API. */
@@ -64,4 +64,4 @@ export const isAuthSwitchAccountLabel = (value) => typeof value === 'string'
64
64
  && value.trim() === value && value.length > 0 && value.length <= authSwitchAccountLabelMaxLength
65
65
  && !/[\u0000-\u001f\u007f]/.test(value);
66
66
  /** Runtime capability is returned only to trusted backend callers; do not expose this response in a browser API. */
67
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aG9yaXR5LWNvbnRyYWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvYXV0aG9yaXR5LWNvbnRyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXFDQSw2RkFBNkY7QUFDN0YsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsMkJBQTJCLENBQUM7QUFDekUsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsb0JBQW9CLENBQUM7QUFpQjVELE1BQU0sWUFBWSxHQUF3QixJQUFJLEdBQUcsQ0FBeUI7SUFDeEUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLGNBQWM7SUFDbkUsbUJBQW1CLEVBQUUsc0JBQXNCLEVBQUUsMEJBQTBCLEVBQUUsMEJBQTBCO0lBQ25HLHdCQUF3QixFQUFFLHdCQUF3QixFQUFFLGdCQUFnQjtJQUNwRSx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSxtQkFBbUIsRUFBRSxlQUFlO0lBQ3RGLG9CQUFvQixFQUFFLGtCQUFrQjtDQUN6QyxDQUFDLENBQUM7QUFFSCxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQWMsRUFBbUMsRUFBRSxDQUN4RSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV2RCwrRkFBK0Y7QUFDL0YsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUE0QixFQUE0QixFQUFFLENBQzFFLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDO0FBRXRGOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGlCQUFrQixTQUFRLEtBQUs7SUFDMUIsSUFBSSxDQUF5QjtJQUU3QyxZQUFZLElBQTRCLEVBQUUsV0FBbUI7UUFDM0QsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsSUFBVyxJQUFJLEtBQTZCLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztDQUN2RztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBYyxFQUE2QixFQUFFO0lBQy9FLElBQUksS0FBSyxZQUFZLGlCQUFpQjtRQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hHLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN4RixNQUFNLElBQUksR0FBWSxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ3RDLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNsRixNQUFNLElBQUksR0FBWSxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDN0QsTUFBTSxXQUFXLEdBQUcsU0FBUyxJQUFJLEtBQUssSUFBSSxPQUFPLEtBQUssQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDakcsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLDZCQUE2QixFQUFFLENBQUM7UUFDbEQsT0FBTyxJQUFJLEtBQUssU0FBUyxJQUFJLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUMxRyxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLHVCQUF1QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ2pGLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7QUFDL0IsQ0FBQyxDQUFDO0FBRUYsdURBQXVEO0FBQ3ZELE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLEdBQUcsQ0FBQztBQUVuRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxLQUFjLEVBQW1CLEVBQUUsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRO09BQ2pHLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSwrQkFBK0I7T0FDN0YsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUE4YTFDLG9IQUFvSCJ9
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aG9yaXR5LWNvbnRyYWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvYXV0aG9yaXR5LWNvbnRyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXFDQSw2RkFBNkY7QUFDN0YsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsMkJBQTJCLENBQUM7QUFDekUsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsb0JBQW9CLENBQUM7QUFpQjVELE1BQU0sWUFBWSxHQUF3QixJQUFJLEdBQUcsQ0FBeUI7SUFDeEUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLGNBQWM7SUFDbkUsbUJBQW1CLEVBQUUsc0JBQXNCLEVBQUUsMEJBQTBCLEVBQUUsMEJBQTBCO0lBQ25HLHdCQUF3QixFQUFFLHdCQUF3QixFQUFFLGdCQUFnQjtJQUNwRSx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSxtQkFBbUIsRUFBRSxlQUFlO0lBQ3RGLG9CQUFvQixFQUFFLGtCQUFrQjtDQUN6QyxDQUFDLENBQUM7QUFFSCxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQWMsRUFBbUMsRUFBRSxDQUN4RSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV2RCwrRkFBK0Y7QUFDL0YsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUE0QixFQUE0QixFQUFFLENBQzFFLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDO0FBRXRGOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGlCQUFrQixTQUFRLEtBQUs7SUFDMUIsSUFBSSxDQUF5QjtJQUU3QyxZQUFZLElBQTRCLEVBQUUsV0FBbUI7UUFDM0QsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsSUFBVyxJQUFJLEtBQTZCLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztDQUN2RztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBYyxFQUE2QixFQUFFO0lBQy9FLElBQUksS0FBSyxZQUFZLGlCQUFpQjtRQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hHLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN4RixNQUFNLElBQUksR0FBWSxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ3RDLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNsRixNQUFNLElBQUksR0FBWSxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDN0QsTUFBTSxXQUFXLEdBQUcsU0FBUyxJQUFJLEtBQUssSUFBSSxPQUFPLEtBQUssQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDakcsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLDZCQUE2QixFQUFFLENBQUM7UUFDbEQsT0FBTyxJQUFJLEtBQUssU0FBUyxJQUFJLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUMxRyxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLHVCQUF1QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ2pGLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7QUFDL0IsQ0FBQyxDQUFDO0FBRUYsdURBQXVEO0FBQ3ZELE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLEdBQUcsQ0FBQztBQUVuRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxLQUFjLEVBQW1CLEVBQUUsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRO09BQ2pHLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSwrQkFBK0I7T0FDN0YsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFrZTFDLG9IQUFvSCJ9
@@ -26,6 +26,35 @@ export interface IReq_AuthSwitchBindAccount extends ITypedRequest {
26
26
  capability: string;
27
27
  };
28
28
  }
29
+ /**
30
+ * Backend-only release of a binding by the identity its holder bound it under, served on the MANAGEMENT
31
+ * socket beside `bind`, of which it is the inverse.
32
+ *
33
+ * It is how a holder releases a binding it no longer holds the capability for -- one an earlier run of it
34
+ * left behind -- and it needs no ready login: an account whose sign-in has ended can have its leftover
35
+ * bindings released, and then be removed, without signing in again first. It is authorized as `bind` is: a
36
+ * caller trusted with the management socket names a runtime and scope, the namespace a holder binds under
37
+ * and owns. It releases only the binding at exactly that runtime and scope, and only while it is still the
38
+ * incarnation and revision the holder read from the snapshot or `getBinding`; any other binding -- another
39
+ * scope, another runtime, or a successor bound meanwhile -- is left alone and the answer is `inactive`.
40
+ * A binding's revision names one bind and never repeats for its runtime and scope, so a successor is told
41
+ * apart even when it was bound under the same incarnation after the one read was released.
42
+ * The daemon's own managed Codex bindings are never named here. Like the runtime release, it waits for
43
+ * the access resolutions already admitted for that binding.
44
+ */
45
+ export interface IReq_AuthSwitchUnbind extends ITypedRequest {
46
+ method: 'authswitch.authority.unbind';
47
+ request: {
48
+ runtime: Exclude<IAuthSwitchBinding['runtime'], 'codex'>;
49
+ scopeId: string;
50
+ incarnationId: string;
51
+ /** The binding's `revision` as the holder read it. */
52
+ expectedRevision: number;
53
+ };
54
+ response: {
55
+ state: 'released' | 'inactive';
56
+ };
57
+ }
29
58
  /** Backend-only access operation. Refresh grants never cross this interface. */
30
59
  export interface IReq_AuthSwitchResolveAccess extends ITypedRequest {
31
60
  method: 'authswitch.authority.resolveAccess';
@@ -1,9 +1,9 @@
1
- import * as plugins from './plugins.js';
2
- import type { IAuthSwitchAccount, IAuthSwitchAccountEvent, IAuthSwitchBinding, IAuthSwitchOperation, IAuthSwitchSnapshot, IReq_AuthSwitchSnapshot } from './authority-contract.js';
1
+ import { AuthSwitchOpenAiProvider } from './classes.openaiprovider.js';
2
+ import type { IAuthSwitchAccount, IAuthSwitchAccountEvent, IAuthSwitchBinding, IAuthSwitchOperation, IAuthSwitchSnapshot, IReq_AuthSwitchSnapshot, TAuthSwitchRevocation } from './authority-contract.js';
3
3
  import { AuthSwitchAuthorityDatabase } from './classes.authoritydatabase.js';
4
4
  import type { IAuthSwitchUsageContext } from './classes.authorityusage.js';
5
5
  import { type IAuthSwitchSecretCodec } from './classes.authoritysecrets.js';
6
- type TOpenAiProvider = Pick<plugins.flexAccounts.ISmartAiProviderAdapter, 'beginLogin' | 'refreshCredential' | 'inspectCredential' | 'getAccountRateLimits' | 'dispose'>;
6
+ type TOpenAiProvider = Pick<AuthSwitchOpenAiProvider, 'beginLogin' | 'refreshCredential' | 'revokeCredential' | 'inspectCredential' | 'getAccountRateLimits' | 'dispose'>;
7
7
  export interface IAuthSwitchAuthorityBrokerOptions {
8
8
  provider?: TOpenAiProvider;
9
9
  secrets?: IAuthSwitchSecretCodec;
@@ -77,7 +77,23 @@ export declare class AuthSwitchAuthorityBroker {
77
77
  waitOperation(operationId: string): Promise<void>;
78
78
  cancelOperation(operationId: string): Promise<IAuthSwitchOperation>;
79
79
  renameAccount(accountId: string, expectedRevision: number, label: string): Promise<IAuthSwitchAccount>;
80
- removeAccount(accountId: string, expectedRevision: number): Promise<IAuthSwitchAccount>;
80
+ /**
81
+ * Removes an account. Only `revoke: true` reaches the network: it revokes the ChatGPT sign-in the removal
82
+ * discarded, after the removal committed.
83
+ */
84
+ removeAccount(accountId: string, expectedRevision: number, options: {
85
+ revoke: boolean;
86
+ }): Promise<{
87
+ account: IAuthSwitchAccount;
88
+ revoked: TAuthSwitchRevocation;
89
+ }>;
90
+ /**
91
+ * Revokes the ChatGPT sign-ins a removal discarded, as Codex revokes its own when it logs out, so that sign-in
92
+ * stops working at the service too. Like Codex's, it is best effort: the account is already removed, and the
93
+ * log says when the service did not confirm the revocation. All of them share `revocationBudgetMs`: each is
94
+ * given what remains of it, and one the budget no longer reaches is not sent and counts as not confirmed.
95
+ */
96
+ private revokeRetired;
81
97
  bindAccount(input: {
82
98
  accountId: string;
83
99
  loginId: string;
@@ -92,6 +108,22 @@ export declare class AuthSwitchAuthorityBroker {
92
108
  getBinding(bindingId: string): Promise<IAuthSwitchBinding | null>;
93
109
  revokeBinding(bindingId: string, capability: string): Promise<boolean>;
94
110
  releaseExternalBinding(bindingId: string, capability: string): Promise<'released' | 'inactive'>;
111
+ /** Releases a caller-held binding while it still carries exactly this capability, named by its hash. */
112
+ releaseExternalCapability(bindingId: string, capabilityHash: string): Promise<'released' | 'inactive'>;
113
+ /**
114
+ * The caller-held binding a holder names by the identity it bound under, while it is still exactly the
115
+ * incarnation and revision the holder read, or `null`. Its capability hash is what a release then fences
116
+ * and compares, so a successor bound after this read is never released in its place.
117
+ */
118
+ findHeldBinding(input: {
119
+ runtime: Exclude<IAuthSwitchBinding['runtime'], 'codex'>;
120
+ scopeId: string;
121
+ incarnationId: string;
122
+ expectedRevision: number;
123
+ }): Promise<{
124
+ bindingId: string;
125
+ capabilityHash: string;
126
+ } | null>;
95
127
  resolveAccess(bindingId: string, capability: string, minValidityMs: number, rejectedGrantGeneration?: number): Promise<IAuthSwitchResolvedAccess>;
96
128
  /** Backend-only access for usage; it never creates or bypasses a runtime binding. */
97
129
  resolveUsageAccess(context: IAuthSwitchUsageContext, rejectedGrantGeneration: number | undefined, minValidityMs: number): Promise<IAuthSwitchResolvedAccess>;