@cortexkit/antigravity-auth-core 2.2.1 → 3.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 (230) hide show
  1. package/README.md +24 -2
  2. package/dist/abort-forwarding.d.ts +3 -0
  3. package/dist/abort-forwarding.d.ts.map +1 -0
  4. package/dist/abort-forwarding.js +19 -0
  5. package/dist/abort-forwarding.js.map +1 -0
  6. package/dist/account-identity.d.ts +52 -0
  7. package/dist/account-identity.d.ts.map +1 -0
  8. package/dist/account-identity.js +66 -0
  9. package/dist/account-identity.js.map +1 -0
  10. package/dist/account-manager.d.ts +228 -43
  11. package/dist/account-manager.d.ts.map +1 -1
  12. package/dist/account-manager.js +942 -903
  13. package/dist/account-manager.js.map +1 -1
  14. package/dist/account-migration.d.ts +309 -0
  15. package/dist/account-migration.d.ts.map +1 -0
  16. package/dist/account-migration.js +2282 -0
  17. package/dist/account-migration.js.map +1 -0
  18. package/dist/account-repository-codecs.d.ts +82 -0
  19. package/dist/account-repository-codecs.d.ts.map +1 -0
  20. package/dist/account-repository-codecs.js +609 -0
  21. package/dist/account-repository-codecs.js.map +1 -0
  22. package/dist/account-repository-types.d.ts +831 -0
  23. package/dist/account-repository-types.d.ts.map +1 -0
  24. package/dist/account-repository-types.js +137 -0
  25. package/dist/account-repository-types.js.map +1 -0
  26. package/dist/account-repository.d.ts +442 -0
  27. package/dist/account-repository.d.ts.map +1 -0
  28. package/dist/account-repository.js +2253 -0
  29. package/dist/account-repository.js.map +1 -0
  30. package/dist/account-selector.d.ts +470 -0
  31. package/dist/account-selector.d.ts.map +1 -0
  32. package/dist/account-selector.js +1383 -0
  33. package/dist/account-selector.js.map +1 -0
  34. package/dist/account-storage.d.ts.map +1 -1
  35. package/dist/account-storage.js +5 -0
  36. package/dist/account-storage.js.map +1 -1
  37. package/dist/agy-transport.d.ts.map +1 -1
  38. package/dist/agy-transport.js +21 -35
  39. package/dist/agy-transport.js.map +1 -1
  40. package/dist/antigravity-command-menu.d.ts +171 -0
  41. package/dist/antigravity-command-menu.d.ts.map +1 -0
  42. package/dist/antigravity-command-menu.js +523 -0
  43. package/dist/antigravity-command-menu.js.map +1 -0
  44. package/dist/atomic-write.d.ts +18 -1
  45. package/dist/atomic-write.d.ts.map +1 -1
  46. package/dist/atomic-write.js +15 -3
  47. package/dist/atomic-write.js.map +1 -1
  48. package/dist/common-auth-embedded/NOTICE.txt +21 -0
  49. package/dist/common-auth-embedded/auth-menu/accounts.d.ts +97 -0
  50. package/dist/common-auth-embedded/auth-menu/accounts.js +387 -0
  51. package/dist/common-auth-embedded/auth-menu/ansi.d.ts +26 -0
  52. package/dist/common-auth-embedded/auth-menu/ansi.js +98 -0
  53. package/dist/common-auth-embedded/auth-menu/confirm.d.ts +7 -0
  54. package/dist/common-auth-embedded/auth-menu/confirm.js +21 -0
  55. package/dist/common-auth-embedded/auth-menu/doctor.d.ts +52 -0
  56. package/dist/common-auth-embedded/auth-menu/doctor.js +81 -0
  57. package/dist/common-auth-embedded/auth-menu/index.d.ts +17 -0
  58. package/dist/common-auth-embedded/auth-menu/index.js +12 -0
  59. package/dist/common-auth-embedded/auth-menu/login.d.ts +55 -0
  60. package/dist/common-auth-embedded/auth-menu/login.js +83 -0
  61. package/dist/common-auth-embedded/auth-menu/menu.d.ts +59 -0
  62. package/dist/common-auth-embedded/auth-menu/menu.js +73 -0
  63. package/dist/common-auth-embedded/auth-menu/opencode-v1.d.ts +49 -0
  64. package/dist/common-auth-embedded/auth-menu/opencode-v1.js +47 -0
  65. package/dist/common-auth-embedded/auth-menu/select.d.ts +21 -0
  66. package/dist/common-auth-embedded/auth-menu/select.js +159 -0
  67. package/dist/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
  68. package/dist/common-auth-embedded/auth-menu/terminal.js +19 -0
  69. package/dist/common-auth-embedded/claustrum/consumer.d.ts +102 -0
  70. package/dist/common-auth-embedded/claustrum/consumer.js +298 -0
  71. package/dist/common-auth-embedded/claustrum/custody.d.ts +175 -0
  72. package/dist/common-auth-embedded/claustrum/custody.js +354 -0
  73. package/dist/common-auth-embedded/claustrum/enrollment.d.ts +158 -0
  74. package/dist/common-auth-embedded/claustrum/enrollment.js +759 -0
  75. package/dist/common-auth-embedded/claustrum/errors.d.ts +16 -0
  76. package/dist/common-auth-embedded/claustrum/errors.js +8 -0
  77. package/dist/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
  78. package/dist/common-auth-embedded/claustrum/host-slot.js +72 -0
  79. package/dist/common-auth-embedded/claustrum/index.d.ts +18 -0
  80. package/dist/common-auth-embedded/claustrum/index.js +22 -0
  81. package/dist/common-auth-embedded/claustrum/interlock.d.ts +27 -0
  82. package/dist/common-auth-embedded/claustrum/interlock.js +29 -0
  83. package/dist/common-auth-embedded/claustrum/roster.d.ts +208 -0
  84. package/dist/common-auth-embedded/claustrum/roster.js +536 -0
  85. package/dist/common-auth-embedded/commands/builtins.d.ts +71 -0
  86. package/dist/common-auth-embedded/commands/builtins.js +534 -0
  87. package/dist/common-auth-embedded/commands/index.d.ts +10 -0
  88. package/dist/common-auth-embedded/commands/index.js +5 -0
  89. package/dist/common-auth-embedded/commands/menu.d.ts +61 -0
  90. package/dist/common-auth-embedded/commands/menu.js +300 -0
  91. package/dist/common-auth-embedded/commands/model.d.ts +238 -0
  92. package/dist/common-auth-embedded/commands/model.js +16 -0
  93. package/dist/common-auth-embedded/commands/pi.d.ts +23 -0
  94. package/dist/common-auth-embedded/commands/pi.js +206 -0
  95. package/dist/common-auth-embedded/commands/seam.d.ts +72 -0
  96. package/dist/common-auth-embedded/commands/seam.js +301 -0
  97. package/dist/common-auth-embedded/fs/atomic-write.d.ts +20 -0
  98. package/dist/common-auth-embedded/fs/atomic-write.js +80 -0
  99. package/dist/common-auth-embedded/fs/index.d.ts +7 -0
  100. package/dist/common-auth-embedded/fs/index.js +6 -0
  101. package/dist/common-auth-embedded/fs/lock-constants.d.ts +14 -0
  102. package/dist/common-auth-embedded/fs/lock-constants.js +14 -0
  103. package/dist/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
  104. package/dist/common-auth-embedded/fs/refresh-file-lock.js +501 -0
  105. package/dist/common-auth-embedded/fs/with-lock.d.ts +33 -0
  106. package/dist/common-auth-embedded/fs/with-lock.js +48 -0
  107. package/dist/common-auth-embedded/logger/capture-sink.d.ts +14 -0
  108. package/dist/common-auth-embedded/logger/capture-sink.js +13 -0
  109. package/dist/common-auth-embedded/logger/engine.d.ts +100 -0
  110. package/dist/common-auth-embedded/logger/engine.js +246 -0
  111. package/dist/common-auth-embedded/logger/index.d.ts +6 -0
  112. package/dist/common-auth-embedded/logger/index.js +3 -0
  113. package/dist/common-auth-embedded/logger/redact.d.ts +11 -0
  114. package/dist/common-auth-embedded/logger/redact.js +83 -0
  115. package/dist/common-auth-embedded/pi-slot/index.d.ts +3 -0
  116. package/dist/common-auth-embedded/pi-slot/index.js +2 -0
  117. package/dist/common-auth-embedded/pi-slot/lock.js +212 -0
  118. package/dist/common-auth-embedded/pi-slot/slot.d.ts +49 -0
  119. package/dist/common-auth-embedded/pi-slot/slot.js +383 -0
  120. package/dist/common-auth-embedded/quota/codec.d.ts +11 -0
  121. package/dist/common-auth-embedded/quota/codec.js +12 -0
  122. package/dist/common-auth-embedded/quota/format.d.ts +46 -0
  123. package/dist/common-auth-embedded/quota/format.js +138 -0
  124. package/dist/common-auth-embedded/quota/index.d.ts +10 -0
  125. package/dist/common-auth-embedded/quota/index.js +5 -0
  126. package/dist/common-auth-embedded/quota/map.d.ts +63 -0
  127. package/dist/common-auth-embedded/quota/map.js +105 -0
  128. package/dist/common-auth-embedded/quota/merge.d.ts +48 -0
  129. package/dist/common-auth-embedded/quota/merge.js +162 -0
  130. package/dist/common-auth-embedded/quota/projection.d.ts +64 -0
  131. package/dist/common-auth-embedded/quota/projection.js +134 -0
  132. package/dist/common-auth-embedded/routing/admission.d.ts +93 -0
  133. package/dist/common-auth-embedded/routing/admission.js +142 -0
  134. package/dist/common-auth-embedded/routing/index.d.ts +8 -0
  135. package/dist/common-auth-embedded/routing/index.js +4 -0
  136. package/dist/common-auth-embedded/routing/ordered.d.ts +47 -0
  137. package/dist/common-auth-embedded/routing/ordered.js +58 -0
  138. package/dist/common-auth-embedded/routing/pins.d.ts +22 -0
  139. package/dist/common-auth-embedded/routing/pins.js +34 -0
  140. package/dist/common-auth-embedded/routing/sticky.d.ts +158 -0
  141. package/dist/common-auth-embedded/routing/sticky.js +339 -0
  142. package/dist/common-auth-embedded/source-output.json +1090 -0
  143. package/dist/common-auth-embedded/store/attribution.d.ts +28 -0
  144. package/dist/common-auth-embedded/store/attribution.js +60 -0
  145. package/dist/common-auth-embedded/store/errors.d.ts +55 -0
  146. package/dist/common-auth-embedded/store/errors.js +38 -0
  147. package/dist/common-auth-embedded/store/hooks.d.ts +12 -0
  148. package/dist/common-auth-embedded/store/hooks.js +34 -0
  149. package/dist/common-auth-embedded/store/identity.d.ts +39 -0
  150. package/dist/common-auth-embedded/store/identity.js +79 -0
  151. package/dist/common-auth-embedded/store/index.d.ts +21 -0
  152. package/dist/common-auth-embedded/store/index.js +7 -0
  153. package/dist/common-auth-embedded/store/mutate.d.ts +189 -0
  154. package/dist/common-auth-embedded/store/mutate.js +500 -0
  155. package/dist/common-auth-embedded/store/pool.d.ts +196 -0
  156. package/dist/common-auth-embedded/store/pool.js +120 -0
  157. package/dist/common-auth-embedded/store/provider-state.d.ts +131 -0
  158. package/dist/common-auth-embedded/store/provider-state.js +226 -0
  159. package/dist/common-auth-embedded/store/publication.d.ts +47 -0
  160. package/dist/common-auth-embedded/store/publication.js +304 -0
  161. package/dist/common-auth-embedded/store/pull.d.ts +36 -0
  162. package/dist/common-auth-embedded/store/pull.js +143 -0
  163. package/dist/common-auth-embedded/store/refresh-lock.d.ts +63 -0
  164. package/dist/common-auth-embedded/store/refresh-lock.js +136 -0
  165. package/dist/common-auth-embedded/store/refresh.d.ts +72 -0
  166. package/dist/common-auth-embedded/store/refresh.js +225 -0
  167. package/dist/common-auth-embedded/store/reserved.js +13 -0
  168. package/dist/common-auth-embedded/store/rows.d.ts +313 -0
  169. package/dist/common-auth-embedded/store/rows.js +1258 -0
  170. package/dist/common-auth-embedded/store/runtime.d.ts +36 -0
  171. package/dist/common-auth-embedded/store/runtime.js +68 -0
  172. package/dist/common-auth-embedded/store/schema.d.ts +443 -0
  173. package/dist/common-auth-embedded/store/schema.js +754 -0
  174. package/dist/common-auth-embedded/store/settings.d.ts +63 -0
  175. package/dist/common-auth-embedded/store/settings.js +120 -0
  176. package/dist/common-auth-embedded/store/torn.d.ts +78 -0
  177. package/dist/common-auth-embedded/store/torn.js +294 -0
  178. package/dist/common-auth-embedded/util/any-signal.js +42 -0
  179. package/dist/common-auth-runtime.d.ts +73 -0
  180. package/dist/common-auth-runtime.d.ts.map +1 -0
  181. package/dist/common-auth-runtime.js +65 -0
  182. package/dist/common-auth-runtime.js.map +1 -0
  183. package/dist/credential-redaction.d.ts +13 -0
  184. package/dist/credential-redaction.d.ts.map +1 -0
  185. package/dist/credential-redaction.js +230 -0
  186. package/dist/credential-redaction.js.map +1 -0
  187. package/dist/fetch-timeout.d.ts +4 -2
  188. package/dist/fetch-timeout.d.ts.map +1 -1
  189. package/dist/fetch-timeout.js +121 -14
  190. package/dist/fetch-timeout.js.map +1 -1
  191. package/dist/index.d.ts +16 -1
  192. package/dist/index.d.ts.map +1 -1
  193. package/dist/index.js +15 -0
  194. package/dist/index.js.map +1 -1
  195. package/dist/quota-manager.d.ts.map +1 -1
  196. package/dist/quota-manager.js +35 -10
  197. package/dist/quota-manager.js.map +1 -1
  198. package/dist/quota-presentation.d.ts +10 -0
  199. package/dist/quota-presentation.d.ts.map +1 -0
  200. package/dist/quota-presentation.js +60 -0
  201. package/dist/quota-presentation.js.map +1 -0
  202. package/dist/quota-types.d.ts +2 -0
  203. package/dist/quota-types.d.ts.map +1 -1
  204. package/dist/rotation.d.ts +8 -0
  205. package/dist/rotation.d.ts.map +1 -1
  206. package/dist/rotation.js +24 -0
  207. package/dist/rotation.js.map +1 -1
  208. package/dist/transform/claude.d.ts +7 -3
  209. package/dist/transform/claude.d.ts.map +1 -1
  210. package/dist/transform/claude.js +6 -2
  211. package/dist/transform/claude.js.map +1 -1
  212. package/dist/transform/types.d.ts +1 -1
  213. package/dist/transform/types.d.ts.map +1 -1
  214. package/dist/vault-account-source.d.ts +183 -0
  215. package/dist/vault-account-source.d.ts.map +1 -0
  216. package/dist/vault-account-source.js +296 -0
  217. package/dist/vault-account-source.js.map +1 -0
  218. package/dist/vault-enrollment-authority.d.ts +16 -0
  219. package/dist/vault-enrollment-authority.d.ts.map +1 -0
  220. package/dist/vault-enrollment-authority.js +19 -0
  221. package/dist/vault-enrollment-authority.js.map +1 -0
  222. package/dist/vault-family.d.ts +11 -0
  223. package/dist/vault-family.d.ts.map +1 -0
  224. package/dist/vault-family.js +24 -0
  225. package/dist/vault-family.js.map +1 -0
  226. package/dist/vault-provider-state.d.ts +162 -0
  227. package/dist/vault-provider-state.d.ts.map +1 -0
  228. package/dist/vault-provider-state.js +422 -0
  229. package/dist/vault-provider-state.js.map +1 -0
  230. package/package.json +39 -2
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Every refusal the `/claustrum` code raises itself. Refusals sent by the
3
+ * vault keep arriving as the client's own `ClaustrumCredentialError` (a
4
+ * `code`, a `class` and an `action`), so callers can tell the vault's verdict
5
+ * apart from a check made on this side.
6
+ */
7
+ export type ClaustrumConsumerFailureKind = 'closed' | 'not-enrolled' | 'invalid-token' | 'unavailable' | 'identity-changed' | 'identity-unasserted' | 'insufficient-validity' | 'invalid-material' | 'not-active' | 'route-unavailable' | 'route-declined' | 'no-receipt' | 'unsafe-file' | 'invalid-state' | 'wrong-consumer' | 'roster-busy' | 'host-slot-login' | 'host-slot-placeholder' | 'placeholder-refresh';
8
+ export declare class ClaustrumConsumerError extends Error {
9
+ readonly kind: ClaustrumConsumerFailureKind;
10
+ constructor(kind: ClaustrumConsumerFailureKind, message: string);
11
+ }
12
+ /** The structural logger every class here accepts; `/logger`'s `createLogger` satisfies it. */
13
+ export interface ClaustrumLogger {
14
+ warn(message: string, data?: unknown): void;
15
+ debug(message: string, data?: unknown): void;
16
+ }
@@ -0,0 +1,8 @@
1
+ export class ClaustrumConsumerError extends Error {
2
+ kind;
3
+ constructor(kind, message) {
4
+ super(message);
5
+ this.name = 'ClaustrumConsumerError';
6
+ this.kind = kind;
7
+ }
8
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The host's own auth slot (OpenCode's stored login for the provider, Pi's
3
+ * equivalent) must hold something, or the host drops the provider. Under
4
+ * custody it holds this placeholder: an OAuth-shaped value that is never a
5
+ * credential. Its empty access token also makes the vault's sealer refuse it,
6
+ * should it ever be offered for import.
7
+ */
8
+ export declare const CUSTODY_PLACEHOLDER_PREFIX = "claustrum-tombstone:v1:";
9
+ export declare function custodyPlaceholderKey(provider: string): string;
10
+ export declare function custodyPlaceholder(provider: string): {
11
+ type: 'oauth';
12
+ access: '';
13
+ refresh: string;
14
+ expires: 0;
15
+ };
16
+ export declare function isCustodyPlaceholderValue(value: unknown): value is string;
17
+ export declare function isCustodyPlaceholder(auth: unknown, provider: string): boolean;
18
+ /** What the host slot holds: the custody placeholder, a real login, or nothing usable. */
19
+ export type HostSlotContent = 'placeholder' | 'login' | 'empty';
20
+ export declare function classifyHostSlot(auth: unknown, provider: string): HostSlotContent;
21
+ /**
22
+ * Check the host slot against the plugin's mode before serving anything.
23
+ *
24
+ * - Custody mode with a real login in the slot fails closed: someone signed in
25
+ * through the host while the vault owns the accounts, and serving either the
26
+ * login or the vault would silently pick one. The plugin surfaces the error
27
+ * and the user chooses (leave custody, or remove the login).
28
+ * - Local mode with the placeholder in the slot also fails: there is no local
29
+ * credential to serve, and the user has to sign in.
30
+ *
31
+ * Returns the slot content when the combination is consistent.
32
+ */
33
+ export declare function assertHostSlotMatchesMode(input: {
34
+ mode: 'custody' | 'local';
35
+ auth: unknown;
36
+ provider: string;
37
+ }): HostSlotContent;
38
+ /** Refuse to run a local token refresh with the placeholder as the refresh token. */
39
+ export declare function assertNotCustodyPlaceholder(refreshToken: unknown, provider: string): void;
@@ -0,0 +1,72 @@
1
+ import { ClaustrumConsumerError } from './errors.js';
2
+ /**
3
+ * The host's own auth slot (OpenCode's stored login for the provider, Pi's
4
+ * equivalent) must hold something, or the host drops the provider. Under
5
+ * custody it holds this placeholder: an OAuth-shaped value that is never a
6
+ * credential. Its empty access token also makes the vault's sealer refuse it,
7
+ * should it ever be offered for import.
8
+ */
9
+ export const CUSTODY_PLACEHOLDER_PREFIX = 'claustrum-tombstone:v1:';
10
+ export function custodyPlaceholderKey(provider) {
11
+ return `${CUSTODY_PLACEHOLDER_PREFIX}${provider}`;
12
+ }
13
+ export function custodyPlaceholder(provider) {
14
+ return {
15
+ type: 'oauth',
16
+ access: '',
17
+ refresh: custodyPlaceholderKey(provider),
18
+ expires: 0,
19
+ };
20
+ }
21
+ function isRecord(value) {
22
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
23
+ }
24
+ export function isCustodyPlaceholderValue(value) {
25
+ return (typeof value === 'string' && value.startsWith(CUSTODY_PLACEHOLDER_PREFIX));
26
+ }
27
+ export function isCustodyPlaceholder(auth, provider) {
28
+ if (!isRecord(auth) || auth.type !== 'oauth')
29
+ return false;
30
+ return auth.refresh === custodyPlaceholderKey(provider);
31
+ }
32
+ export function classifyHostSlot(auth, provider) {
33
+ if (isCustodyPlaceholder(auth, provider))
34
+ return 'placeholder';
35
+ if (isRecord(auth) &&
36
+ auth.type === 'oauth' &&
37
+ typeof auth.refresh === 'string' &&
38
+ auth.refresh.length > 0 &&
39
+ !isCustodyPlaceholderValue(auth.refresh))
40
+ return 'login';
41
+ if (isRecord(auth) &&
42
+ auth.type === 'api' &&
43
+ typeof auth.key === 'string' &&
44
+ auth.key.length > 0)
45
+ return 'login';
46
+ return 'empty';
47
+ }
48
+ /**
49
+ * Check the host slot against the plugin's mode before serving anything.
50
+ *
51
+ * - Custody mode with a real login in the slot fails closed: someone signed in
52
+ * through the host while the vault owns the accounts, and serving either the
53
+ * login or the vault would silently pick one. The plugin surfaces the error
54
+ * and the user chooses (leave custody, or remove the login).
55
+ * - Local mode with the placeholder in the slot also fails: there is no local
56
+ * credential to serve, and the user has to sign in.
57
+ *
58
+ * Returns the slot content when the combination is consistent.
59
+ */
60
+ export function assertHostSlotMatchesMode(input) {
61
+ const content = classifyHostSlot(input.auth, input.provider);
62
+ if (input.mode === 'custody' && content === 'login')
63
+ throw new ClaustrumConsumerError('host-slot-login', `${input.provider} has a host login while its accounts are vault-custodied; refusing to serve until one is removed`);
64
+ if (input.mode === 'local' && content === 'placeholder')
65
+ throw new ClaustrumConsumerError('host-slot-placeholder', `${input.provider} host slot holds the vault placeholder; sign in to use local accounts`);
66
+ return content;
67
+ }
68
+ /** Refuse to run a local token refresh with the placeholder as the refresh token. */
69
+ export function assertNotCustodyPlaceholder(refreshToken, provider) {
70
+ if (isCustodyPlaceholderValue(refreshToken))
71
+ throw new ClaustrumConsumerError('placeholder-refresh', `${provider} credentials are vault-custodied; local token refresh is forbidden`);
72
+ }
@@ -0,0 +1,18 @@
1
+ import { type ClaustrumClientOptions } from '@cortexkit/claustrum-client';
2
+ import type { ClaustrumScopedClient } from './custody.js';
3
+ export { ClaustrumCredentialError, type ClaustrumReporterSource, type EnrollmentTokenFile, } from '@cortexkit/claustrum-client';
4
+ export { ClaustrumConsumer, type ClaustrumConsumerOptions, type SendOptions, } from './consumer.js';
5
+ export { type AccountIdentitySource, type ClaustrumFamily, type ClaustrumScopedAttempt, type ClaustrumScopedClient, ClaustrumScopedCustody, type ClaustrumScopedIdentity, decideScopedRetryAfter401, type IdentityParser, isScopedCredentialRotation, type ScopedRetryReason, SERVING_MARGIN_MS, type SkippedVaultReason, type SkippedVaultRecord, type VaultCredential, type VaultCredentialType, type VaultInventory, } from './custody.js';
6
+ export { type ClaustrumEnrollmentClient, type ClaustrumEnrollmentConnection, type ClaustrumEnrollmentDisconnectResult, ClaustrumEnrollmentManager, type ClaustrumEnrollmentPaths, type ClaustrumEnrollmentResetResult, type ClaustrumEnrollmentStatus, classifyEnrollmentError, connectClaustrumEnrollmentClient, disconnectClaustrumEnrollment, type EnrollmentDisposition, enrollmentAuthority, enrollmentName, getClaustrumEnrollmentPaths, hostEnrollmentPaths, RETRYABLE_ENROLLMENT_CODES, readClaustrumEnrollmentStatus, readClaustrumEnrollmentToken, resetClaustrumEnrollmentState, TERMINAL_ENROLLMENT_CODES, } from './enrollment.js';
7
+ export { ClaustrumConsumerError, type ClaustrumConsumerFailureKind, type ClaustrumLogger, } from './errors.js';
8
+ export { assertHostSlotMatchesMode, assertNotCustodyPlaceholder, CUSTODY_PLACEHOLDER_PREFIX, classifyHostSlot, custodyPlaceholder, custodyPlaceholderKey, type HostSlotContent, isCustodyPlaceholder, isCustodyPlaceholderValue, } from './host-slot.js';
9
+ export { acceptAccount, type DeclinedAccount, declineAccount, isDeclined, } from './interlock.js';
10
+ export { type AccountMapper, acceptVaultRoute, DEFAULT_ROUTE_PREFIX, declineVaultRoute, type MutateVaultRosterOptions, mutateVaultRoster, type ProjectionOptions, projectVaultRoster, type QuotaReceipt, readVaultRoster, recordVaultQuota, refreshVaultRoster, resolveVaultPrimary, type VaultPrimary, type VaultPrimaryBinding, type VaultPrimaryUnavailableReason, type VaultRosterFile, type VaultRosterLockContext, type VaultRosterRow, vaultRoutingRows, } from './roster.js';
11
+ /**
12
+ * Connect the client that lists and fetches this consumer's vault credentials
13
+ * on the request path. `connectionFile` is required: this library
14
+ * reads no environment, so the plugin resolves the vault's connection file.
15
+ */
16
+ export declare function connectClaustrumScopedClient(options: ClaustrumClientOptions & {
17
+ connectionFile: string;
18
+ }): Promise<ClaustrumScopedClient>;
@@ -0,0 +1,22 @@
1
+ // Claustrum vault custody shared by the auth plugins: scoped enrollment (run
2
+ // from setup), discovery of this consumer's vault accounts as rows for this
3
+ // package's `/routing` subpath, per-send authorization, 401 reporting, the
4
+ // declined-account interlock and the host-slot guard. Needs the optional
5
+ // peer `@cortexkit/claustrum-client`.
6
+ import { ClaustrumClient, } from '@cortexkit/claustrum-client';
7
+ export { ClaustrumCredentialError, } from '@cortexkit/claustrum-client';
8
+ export { ClaustrumConsumer, } from './consumer.js';
9
+ export { ClaustrumScopedCustody, decideScopedRetryAfter401, isScopedCredentialRotation, SERVING_MARGIN_MS, } from './custody.js';
10
+ export { ClaustrumEnrollmentManager, classifyEnrollmentError, connectClaustrumEnrollmentClient, disconnectClaustrumEnrollment, enrollmentAuthority, enrollmentName, getClaustrumEnrollmentPaths, hostEnrollmentPaths, RETRYABLE_ENROLLMENT_CODES, readClaustrumEnrollmentStatus, readClaustrumEnrollmentToken, resetClaustrumEnrollmentState, TERMINAL_ENROLLMENT_CODES, } from './enrollment.js';
11
+ export { ClaustrumConsumerError, } from './errors.js';
12
+ export { assertHostSlotMatchesMode, assertNotCustodyPlaceholder, CUSTODY_PLACEHOLDER_PREFIX, classifyHostSlot, custodyPlaceholder, custodyPlaceholderKey, isCustodyPlaceholder, isCustodyPlaceholderValue, } from './host-slot.js';
13
+ export { acceptAccount, declineAccount, isDeclined, } from './interlock.js';
14
+ export { acceptVaultRoute, DEFAULT_ROUTE_PREFIX, declineVaultRoute, mutateVaultRoster, projectVaultRoster, readVaultRoster, recordVaultQuota, refreshVaultRoster, resolveVaultPrimary, vaultRoutingRows, } from './roster.js';
15
+ /**
16
+ * Connect the client that lists and fetches this consumer's vault credentials
17
+ * on the request path. `connectionFile` is required: this library
18
+ * reads no environment, so the plugin resolves the vault's connection file.
19
+ */
20
+ export function connectClaustrumScopedClient(options) {
21
+ return ClaustrumClient.connect(options);
22
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The declined-account interlock: the user's "do not use this vault account",
3
+ * kept on the consumer side because the vault has no notion of it.
4
+ *
5
+ * A decline follows the provider account, not the vault record: an entry made
6
+ * while the account was known matches any credential id or alias that logs
7
+ * into that same account, so relabelling, adding an alias or removing and
8
+ * re-adding the account never lifts it. A credential id that now logs into a
9
+ * different known account does not match, because that account has its own
10
+ * policy. While either side's account is unknown the entry falls back to the
11
+ * credential id, so an adapter that makes no identity claim cannot slip past
12
+ * it. Never keyed on the record version, so a token refresh cannot lift it.
13
+ */
14
+ export interface DeclinedAccount {
15
+ readonly credentialId: string;
16
+ readonly accountIdentity?: string;
17
+ }
18
+ export declare function isDeclined(entries: readonly DeclinedAccount[], credentialId: string, accountIdentity?: string): boolean;
19
+ export declare function declineAccount(entries: readonly DeclinedAccount[], credentialId: string, accountIdentity?: string): DeclinedAccount[];
20
+ /**
21
+ * Lift every entry that declines a row: the row's credential ids (the
22
+ * representative and its aliases) under the row's account. An entry for a
23
+ * different known account is left alone even when it names one of these
24
+ * credential ids, so accepting a replacement never re-enables the account the
25
+ * user declined.
26
+ */
27
+ export declare function acceptAccount(entries: readonly DeclinedAccount[], credentialIds: readonly string[], accountIdentity?: string): DeclinedAccount[];
@@ -0,0 +1,29 @@
1
+ function matches(entry, credentialId, accountIdentity) {
2
+ if (entry.accountIdentity !== undefined && accountIdentity !== undefined)
3
+ return entry.accountIdentity === accountIdentity;
4
+ return entry.credentialId === credentialId;
5
+ }
6
+ export function isDeclined(entries, credentialId, accountIdentity) {
7
+ return entries.some((entry) => matches(entry, credentialId, accountIdentity));
8
+ }
9
+ export function declineAccount(entries, credentialId, accountIdentity) {
10
+ const entry = {
11
+ credentialId,
12
+ ...(accountIdentity !== undefined && { accountIdentity }),
13
+ };
14
+ return [
15
+ ...entries.filter((existing) => existing.credentialId !== credentialId ||
16
+ existing.accountIdentity !== accountIdentity),
17
+ entry,
18
+ ];
19
+ }
20
+ /**
21
+ * Lift every entry that declines a row: the row's credential ids (the
22
+ * representative and its aliases) under the row's account. An entry for a
23
+ * different known account is left alone even when it names one of these
24
+ * credential ids, so accepting a replacement never re-enables the account the
25
+ * user declined.
26
+ */
27
+ export function acceptAccount(entries, credentialIds, accountIdentity) {
28
+ return entries.filter((entry) => !credentialIds.some((id) => matches(entry, id, accountIdentity)));
29
+ }
@@ -0,0 +1,208 @@
1
+ import { type QuotaMap, type QuotaObservation } from '../quota/index.js';
2
+ import type { RoutingRow } from '../routing/index.js';
3
+ import type { ClaustrumScopedAttempt, ClaustrumScopedCustody, SkippedVaultRecord, VaultCredential, VaultCredentialType, VaultInventory } from './custody.js';
4
+ import { type DeclinedAccount } from './interlock.js';
5
+ /**
6
+ * One vault account as the pool sees it. It carries no bearer material: the
7
+ * access token is fetched from the vault for every send. Several vault
8
+ * records logged into the same provider account collapse into one row, so
9
+ * duplicate logins never count as extra quota.
10
+ */
11
+ export interface VaultRosterRow {
12
+ routeId: string;
13
+ credentialId: string;
14
+ credentialType: VaultCredentialType;
15
+ accountIdentity?: string;
16
+ /** Other credential ids logged into the same provider account. */
17
+ aliases?: string[];
18
+ state: string;
19
+ label: string;
20
+ email?: string;
21
+ orgName?: string;
22
+ enabled: boolean;
23
+ addedAt: number;
24
+ quota?: QuotaMap;
25
+ /**
26
+ * The vault listed this record in a form this consumer could not use, so the
27
+ * row is the last good projection kept as it was rather than dropped.
28
+ */
29
+ stale?: true;
30
+ /**
31
+ * The vault's latest list named no account for `credentialId`, so
32
+ * `accountIdentity` is the last account that credential was known to log
33
+ * into, kept until the vault names one again. It proves neither that the
34
+ * credential still logs into that account nor that it changed accounts.
35
+ */
36
+ unclaimed?: true;
37
+ }
38
+ export interface VaultRosterFile {
39
+ version: 1;
40
+ view?: string;
41
+ /**
42
+ * False when the vault's reply carried records this consumer could not use.
43
+ * An incomplete reply never removes an account it may still hold: every
44
+ * previous member it does not account for is kept.
45
+ */
46
+ complete: boolean;
47
+ /** The unusable records of an incomplete reply: a safe id and a fixed reason. */
48
+ rejected?: SkippedVaultRecord[];
49
+ rows: VaultRosterRow[];
50
+ declined: DeclinedAccount[];
51
+ }
52
+ /** How a vault credential is presented in the pool. */
53
+ export type AccountMapper = (credential: VaultCredential) => {
54
+ label?: string;
55
+ };
56
+ export interface ProjectionOptions {
57
+ /** Ids already used by local rows; a vault route never takes one. */
58
+ reservedRouteIds?: ReadonlySet<string>;
59
+ /** Prefix for vault route ids, so they read differently from local ids. */
60
+ routePrefix?: string;
61
+ mapAccount?: AccountMapper;
62
+ now?: number;
63
+ }
64
+ export declare const DEFAULT_ROUTE_PREFIX = "vault:";
65
+ /**
66
+ * Project the vault's list onto the previous roster. Pure: callers serialize
67
+ * discovery and commit. Route ids, quota and the time an account was added
68
+ * survive for the same account; a credential that now logs into a different
69
+ * known account gets a new route id and no inherited quota.
70
+ *
71
+ * A record listed without an identity keeps the last account it was known to
72
+ * log into (the row is marked `unclaimed`). Dropping that binding would let a
73
+ * later different account look like an identity learned for the first time
74
+ * and inherit the first account's route and quota.
75
+ *
76
+ * A reply with unusable records is incomplete: a previous member it does not
77
+ * account for (its record was rejected, or a rejected record has no usable id
78
+ * and could be any of them) is kept, as an alias of its live account or as a
79
+ * `stale` row. Only a complete reply removes an account.
80
+ */
81
+ export declare function projectVaultRoster(previous: VaultRosterFile | undefined, inventory: VaultInventory, options?: ProjectionOptions): VaultRosterFile;
82
+ /**
83
+ * The rows `/routing` selects among. Only enabled, active accounts route;
84
+ * a declined or cold vault account stays listed for the menu but never
85
+ * reaches admission.
86
+ */
87
+ export declare function vaultRoutingRows(roster: VaultRosterFile | undefined): RoutingRow[];
88
+ export declare function readVaultRoster(path: string): Promise<VaultRosterFile | undefined>;
89
+ /** The ownership assertion available to a roster mutation callback. */
90
+ export interface VaultRosterLockContext {
91
+ assertOwned: () => Promise<void>;
92
+ }
93
+ export interface MutateVaultRosterOptions {
94
+ /**
95
+ * Runs when the new roster is fully staged on disk, immediately before the
96
+ * rename that publishes it, so a caller can confirm a lease of its own at
97
+ * the moment of publication rather than when `change` returned. If it
98
+ * throws, nothing is published and the staged file is removed. The
99
+ * roster's own write lock is reasserted right after it.
100
+ */
101
+ beforePublish?: () => Promise<void>;
102
+ }
103
+ /**
104
+ * Read, change and write the roster under its write lock. `change` returns
105
+ * undefined to leave the file as it is. Call `assertOwned()` immediately
106
+ * before any rename performed inside `change`; if it throws, do not rename.
107
+ */
108
+ export declare function mutateVaultRoster<T>(path: string, change: (current: VaultRosterFile | undefined, context: VaultRosterLockContext) => Promise<{
109
+ next?: VaultRosterFile;
110
+ result: T;
111
+ }> | {
112
+ next?: VaultRosterFile;
113
+ result: T;
114
+ }, options?: MutateVaultRosterOptions): Promise<T>;
115
+ /** Mark a vault account declined; it stays listed but never routes. */
116
+ export declare function declineVaultRoute(path: string, routeId: string): Promise<undefined>;
117
+ /** Lift the user's decline for a vault account and every alias of it. */
118
+ export declare function acceptVaultRoute(path: string, routeId: string): Promise<undefined>;
119
+ /**
120
+ * The receipt fields a quota or profile observation must carry to say which
121
+ * send (credential and account) it came from. Pass the
122
+ * `ClaustrumScopedAttempt` that send was authorized with.
123
+ */
124
+ export type QuotaReceipt = Pick<ClaustrumScopedAttempt, 'credentialId' | 'accountIdentity' | 'accountIdentitySource' | 'expectedAccountIdentity'>;
125
+ /**
126
+ * Merge a quota observation into a vault row through `/quota`'s merge. The
127
+ * write is fenced on the receipt the reading was taken with: it lands only
128
+ * while the row still holds that receipt's credential (as representative or
129
+ * alias) and account, so a slow read for a replaced account can never land on
130
+ * its successor. Returns whether the observation was kept.
131
+ */
132
+ export declare function recordVaultQuota(path: string, input: QuotaReceipt & {
133
+ routeId: string;
134
+ observation: QuotaObservation;
135
+ }): Promise<boolean>;
136
+ /**
137
+ * Discover and commit the roster. The lease covers the list call and the
138
+ * commit, not just the write: an opaque view cannot tell a delayed old reply
139
+ * from a newer one, so a run that lost its lease is refused at commit. A
140
+ * failed list, or custody switching off mid-run, never writes anything; a
141
+ * peer holding the lease means its last committed roster is served instead.
142
+ */
143
+ export declare function refreshVaultRoster(options: {
144
+ path: string;
145
+ custody: Pick<ClaustrumScopedCustody, 'discover'>;
146
+ isActive?: () => boolean | Promise<boolean>;
147
+ signal?: AbortSignal;
148
+ projection?: ProjectionOptions | (() => ProjectionOptions);
149
+ }): Promise<VaultRosterFile | undefined>;
150
+ /**
151
+ * A host-owned main account as last verified from the vault: the plugin's
152
+ * logical route, the credential that serves it and the account it logs into.
153
+ */
154
+ export interface VaultPrimaryBinding {
155
+ routeId: string;
156
+ credentialId: string;
157
+ accountIdentity: string;
158
+ view: string;
159
+ }
160
+ export type VaultPrimaryUnavailableReason = 'malformed' | 'unclaimed' | 'incomplete' | 'identity-changed';
161
+ export type VaultPrimary =
162
+ /**
163
+ * Main is bound. `replaced` is the previous binding when it named a
164
+ * different account: everything owned by that account (quota, profile,
165
+ * backoff, cache affinity) must be dropped, and outstanding observations
166
+ * for it fenced, even though the logical route stays the same.
167
+ */
168
+ {
169
+ status: 'ready';
170
+ binding: VaultPrimaryBinding;
171
+ replaced?: VaultPrimaryBinding;
172
+ }
173
+ /** A complete reply lists no primary record: there is no main. */
174
+ | {
175
+ status: 'absent';
176
+ }
177
+ /**
178
+ * The reply cannot say who main is. Not the same as absent: the last
179
+ * verified binding is handed back untouched, and serving it still needs a
180
+ * fresh receipt that matches it.
181
+ */
182
+ | {
183
+ status: 'unavailable';
184
+ reason: VaultPrimaryUnavailableReason;
185
+ lastVerified?: VaultPrimaryBinding;
186
+ };
187
+ /**
188
+ * The seam for a plugin that keeps a main account: one fixed account the host
189
+ * owns under a logical route, outside the pool's rotating rows. The library
190
+ * has no main convention of its own: the plugin names the
191
+ * vault record that holds the role (`primaryCredentialId`) and its logical
192
+ * route. Main follows the account that record claims; another credential of
193
+ * that same account may serve it when the record itself is not active, but a
194
+ * credential of any other account is never promoted into main.
195
+ *
196
+ * Inputs are the plugin's filtered inventory, whether that inventory is
197
+ * complete (defaults to the reply having no unusable records; pass the
198
+ * roster's `complete` or false to override), the previous verified binding
199
+ * and, on the request path, the account the chosen request expects.
200
+ */
201
+ export declare function resolveVaultPrimary(input: {
202
+ inventory: VaultInventory;
203
+ complete?: boolean;
204
+ previous?: VaultPrimaryBinding;
205
+ expectedAccountIdentity?: string;
206
+ primaryCredentialId: string;
207
+ routeId: string;
208
+ }): VaultPrimary;