@cortexkit/antigravity-auth-core 2.2.1 → 3.0.1

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 (253) 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 +2284 -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-request-metadata.d.ts.map +1 -1
  38. package/dist/agy-request-metadata.js +8 -21
  39. package/dist/agy-request-metadata.js.map +1 -1
  40. package/dist/agy-transport.d.ts.map +1 -1
  41. package/dist/agy-transport.js +21 -35
  42. package/dist/agy-transport.js.map +1 -1
  43. package/dist/antigravity-command-menu.d.ts +171 -0
  44. package/dist/antigravity-command-menu.d.ts.map +1 -0
  45. package/dist/antigravity-command-menu.js +523 -0
  46. package/dist/antigravity-command-menu.js.map +1 -0
  47. package/dist/atomic-write.d.ts +18 -1
  48. package/dist/atomic-write.d.ts.map +1 -1
  49. package/dist/atomic-write.js +15 -3
  50. package/dist/atomic-write.js.map +1 -1
  51. package/dist/common-auth-embedded/NOTICE.txt +21 -0
  52. package/dist/common-auth-embedded/auth-menu/accounts.d.ts +97 -0
  53. package/dist/common-auth-embedded/auth-menu/accounts.js +387 -0
  54. package/dist/common-auth-embedded/auth-menu/ansi.d.ts +26 -0
  55. package/dist/common-auth-embedded/auth-menu/ansi.js +98 -0
  56. package/dist/common-auth-embedded/auth-menu/confirm.d.ts +7 -0
  57. package/dist/common-auth-embedded/auth-menu/confirm.js +21 -0
  58. package/dist/common-auth-embedded/auth-menu/doctor.d.ts +52 -0
  59. package/dist/common-auth-embedded/auth-menu/doctor.js +81 -0
  60. package/dist/common-auth-embedded/auth-menu/index.d.ts +17 -0
  61. package/dist/common-auth-embedded/auth-menu/index.js +12 -0
  62. package/dist/common-auth-embedded/auth-menu/login.d.ts +55 -0
  63. package/dist/common-auth-embedded/auth-menu/login.js +83 -0
  64. package/dist/common-auth-embedded/auth-menu/menu.d.ts +59 -0
  65. package/dist/common-auth-embedded/auth-menu/menu.js +73 -0
  66. package/dist/common-auth-embedded/auth-menu/opencode-v1.d.ts +49 -0
  67. package/dist/common-auth-embedded/auth-menu/opencode-v1.js +47 -0
  68. package/dist/common-auth-embedded/auth-menu/select.d.ts +21 -0
  69. package/dist/common-auth-embedded/auth-menu/select.js +159 -0
  70. package/dist/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
  71. package/dist/common-auth-embedded/auth-menu/terminal.js +19 -0
  72. package/dist/common-auth-embedded/claustrum/consumer.d.ts +102 -0
  73. package/dist/common-auth-embedded/claustrum/consumer.js +298 -0
  74. package/dist/common-auth-embedded/claustrum/custody.d.ts +175 -0
  75. package/dist/common-auth-embedded/claustrum/custody.js +354 -0
  76. package/dist/common-auth-embedded/claustrum/enrollment.d.ts +158 -0
  77. package/dist/common-auth-embedded/claustrum/enrollment.js +759 -0
  78. package/dist/common-auth-embedded/claustrum/errors.d.ts +16 -0
  79. package/dist/common-auth-embedded/claustrum/errors.js +8 -0
  80. package/dist/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
  81. package/dist/common-auth-embedded/claustrum/host-slot.js +72 -0
  82. package/dist/common-auth-embedded/claustrum/index.d.ts +18 -0
  83. package/dist/common-auth-embedded/claustrum/index.js +22 -0
  84. package/dist/common-auth-embedded/claustrum/interlock.d.ts +27 -0
  85. package/dist/common-auth-embedded/claustrum/interlock.js +29 -0
  86. package/dist/common-auth-embedded/claustrum/roster.d.ts +208 -0
  87. package/dist/common-auth-embedded/claustrum/roster.js +536 -0
  88. package/dist/common-auth-embedded/commands/builtins.d.ts +71 -0
  89. package/dist/common-auth-embedded/commands/builtins.js +534 -0
  90. package/dist/common-auth-embedded/commands/index.d.ts +10 -0
  91. package/dist/common-auth-embedded/commands/index.js +5 -0
  92. package/dist/common-auth-embedded/commands/menu.d.ts +61 -0
  93. package/dist/common-auth-embedded/commands/menu.js +300 -0
  94. package/dist/common-auth-embedded/commands/model.d.ts +238 -0
  95. package/dist/common-auth-embedded/commands/model.js +16 -0
  96. package/dist/common-auth-embedded/commands/pi.d.ts +23 -0
  97. package/dist/common-auth-embedded/commands/pi.js +206 -0
  98. package/dist/common-auth-embedded/commands/seam.d.ts +72 -0
  99. package/dist/common-auth-embedded/commands/seam.js +301 -0
  100. package/dist/common-auth-embedded/fs/atomic-write.d.ts +20 -0
  101. package/dist/common-auth-embedded/fs/atomic-write.js +80 -0
  102. package/dist/common-auth-embedded/fs/index.d.ts +7 -0
  103. package/dist/common-auth-embedded/fs/index.js +6 -0
  104. package/dist/common-auth-embedded/fs/lock-constants.d.ts +14 -0
  105. package/dist/common-auth-embedded/fs/lock-constants.js +14 -0
  106. package/dist/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
  107. package/dist/common-auth-embedded/fs/refresh-file-lock.js +501 -0
  108. package/dist/common-auth-embedded/fs/with-lock.d.ts +33 -0
  109. package/dist/common-auth-embedded/fs/with-lock.js +48 -0
  110. package/dist/common-auth-embedded/logger/capture-sink.d.ts +14 -0
  111. package/dist/common-auth-embedded/logger/capture-sink.js +13 -0
  112. package/dist/common-auth-embedded/logger/engine.d.ts +100 -0
  113. package/dist/common-auth-embedded/logger/engine.js +246 -0
  114. package/dist/common-auth-embedded/logger/index.d.ts +6 -0
  115. package/dist/common-auth-embedded/logger/index.js +3 -0
  116. package/dist/common-auth-embedded/logger/redact.d.ts +11 -0
  117. package/dist/common-auth-embedded/logger/redact.js +83 -0
  118. package/dist/common-auth-embedded/pi-slot/index.d.ts +3 -0
  119. package/dist/common-auth-embedded/pi-slot/index.js +2 -0
  120. package/dist/common-auth-embedded/pi-slot/lock.js +212 -0
  121. package/dist/common-auth-embedded/pi-slot/slot.d.ts +49 -0
  122. package/dist/common-auth-embedded/pi-slot/slot.js +383 -0
  123. package/dist/common-auth-embedded/quota/codec.d.ts +11 -0
  124. package/dist/common-auth-embedded/quota/codec.js +12 -0
  125. package/dist/common-auth-embedded/quota/format.d.ts +46 -0
  126. package/dist/common-auth-embedded/quota/format.js +138 -0
  127. package/dist/common-auth-embedded/quota/index.d.ts +10 -0
  128. package/dist/common-auth-embedded/quota/index.js +5 -0
  129. package/dist/common-auth-embedded/quota/map.d.ts +63 -0
  130. package/dist/common-auth-embedded/quota/map.js +105 -0
  131. package/dist/common-auth-embedded/quota/merge.d.ts +48 -0
  132. package/dist/common-auth-embedded/quota/merge.js +162 -0
  133. package/dist/common-auth-embedded/quota/projection.d.ts +64 -0
  134. package/dist/common-auth-embedded/quota/projection.js +134 -0
  135. package/dist/common-auth-embedded/routing/admission.d.ts +93 -0
  136. package/dist/common-auth-embedded/routing/admission.js +142 -0
  137. package/dist/common-auth-embedded/routing/index.d.ts +8 -0
  138. package/dist/common-auth-embedded/routing/index.js +4 -0
  139. package/dist/common-auth-embedded/routing/ordered.d.ts +47 -0
  140. package/dist/common-auth-embedded/routing/ordered.js +58 -0
  141. package/dist/common-auth-embedded/routing/pins.d.ts +22 -0
  142. package/dist/common-auth-embedded/routing/pins.js +34 -0
  143. package/dist/common-auth-embedded/routing/sticky.d.ts +158 -0
  144. package/dist/common-auth-embedded/routing/sticky.js +339 -0
  145. package/dist/common-auth-embedded/source-output.json +1090 -0
  146. package/dist/common-auth-embedded/store/attribution.d.ts +28 -0
  147. package/dist/common-auth-embedded/store/attribution.js +60 -0
  148. package/dist/common-auth-embedded/store/errors.d.ts +55 -0
  149. package/dist/common-auth-embedded/store/errors.js +38 -0
  150. package/dist/common-auth-embedded/store/hooks.d.ts +12 -0
  151. package/dist/common-auth-embedded/store/hooks.js +34 -0
  152. package/dist/common-auth-embedded/store/identity.d.ts +39 -0
  153. package/dist/common-auth-embedded/store/identity.js +79 -0
  154. package/dist/common-auth-embedded/store/index.d.ts +21 -0
  155. package/dist/common-auth-embedded/store/index.js +7 -0
  156. package/dist/common-auth-embedded/store/mutate.d.ts +189 -0
  157. package/dist/common-auth-embedded/store/mutate.js +500 -0
  158. package/dist/common-auth-embedded/store/pool.d.ts +196 -0
  159. package/dist/common-auth-embedded/store/pool.js +120 -0
  160. package/dist/common-auth-embedded/store/provider-state.d.ts +131 -0
  161. package/dist/common-auth-embedded/store/provider-state.js +226 -0
  162. package/dist/common-auth-embedded/store/publication.d.ts +47 -0
  163. package/dist/common-auth-embedded/store/publication.js +304 -0
  164. package/dist/common-auth-embedded/store/pull.d.ts +36 -0
  165. package/dist/common-auth-embedded/store/pull.js +143 -0
  166. package/dist/common-auth-embedded/store/refresh-lock.d.ts +63 -0
  167. package/dist/common-auth-embedded/store/refresh-lock.js +136 -0
  168. package/dist/common-auth-embedded/store/refresh.d.ts +72 -0
  169. package/dist/common-auth-embedded/store/refresh.js +225 -0
  170. package/dist/common-auth-embedded/store/reserved.js +13 -0
  171. package/dist/common-auth-embedded/store/rows.d.ts +313 -0
  172. package/dist/common-auth-embedded/store/rows.js +1258 -0
  173. package/dist/common-auth-embedded/store/runtime.d.ts +36 -0
  174. package/dist/common-auth-embedded/store/runtime.js +68 -0
  175. package/dist/common-auth-embedded/store/schema.d.ts +443 -0
  176. package/dist/common-auth-embedded/store/schema.js +754 -0
  177. package/dist/common-auth-embedded/store/settings.d.ts +63 -0
  178. package/dist/common-auth-embedded/store/settings.js +120 -0
  179. package/dist/common-auth-embedded/store/torn.d.ts +78 -0
  180. package/dist/common-auth-embedded/store/torn.js +294 -0
  181. package/dist/common-auth-embedded/util/any-signal.js +42 -0
  182. package/dist/common-auth-runtime.d.ts +73 -0
  183. package/dist/common-auth-runtime.d.ts.map +1 -0
  184. package/dist/common-auth-runtime.js +65 -0
  185. package/dist/common-auth-runtime.js.map +1 -0
  186. package/dist/credential-redaction.d.ts +13 -0
  187. package/dist/credential-redaction.d.ts.map +1 -0
  188. package/dist/credential-redaction.js +230 -0
  189. package/dist/credential-redaction.js.map +1 -0
  190. package/dist/fetch-timeout.d.ts +4 -2
  191. package/dist/fetch-timeout.d.ts.map +1 -1
  192. package/dist/fetch-timeout.js +121 -14
  193. package/dist/fetch-timeout.js.map +1 -1
  194. package/dist/fingerprint.d.ts +3 -3
  195. package/dist/fingerprint.d.ts.map +1 -1
  196. package/dist/fingerprint.js +4 -4
  197. package/dist/fingerprint.js.map +1 -1
  198. package/dist/index.d.ts +16 -1
  199. package/dist/index.d.ts.map +1 -1
  200. package/dist/index.js +15 -0
  201. package/dist/index.js.map +1 -1
  202. package/dist/model-registry.d.ts +16 -0
  203. package/dist/model-registry.d.ts.map +1 -1
  204. package/dist/model-registry.js +242 -30
  205. package/dist/model-registry.js.map +1 -1
  206. package/dist/quota-manager.d.ts.map +1 -1
  207. package/dist/quota-manager.js +35 -10
  208. package/dist/quota-manager.js.map +1 -1
  209. package/dist/quota-presentation.d.ts +10 -0
  210. package/dist/quota-presentation.d.ts.map +1 -0
  211. package/dist/quota-presentation.js +60 -0
  212. package/dist/quota-presentation.js.map +1 -0
  213. package/dist/quota-types.d.ts +2 -0
  214. package/dist/quota-types.d.ts.map +1 -1
  215. package/dist/rotation.d.ts +8 -0
  216. package/dist/rotation.d.ts.map +1 -1
  217. package/dist/rotation.js +24 -0
  218. package/dist/rotation.js.map +1 -1
  219. package/dist/transform/agy-generation.d.ts +3 -0
  220. package/dist/transform/agy-generation.d.ts.map +1 -0
  221. package/dist/transform/agy-generation.js +28 -0
  222. package/dist/transform/agy-generation.js.map +1 -0
  223. package/dist/transform/claude.d.ts +7 -3
  224. package/dist/transform/claude.d.ts.map +1 -1
  225. package/dist/transform/claude.js +8 -2
  226. package/dist/transform/claude.js.map +1 -1
  227. package/dist/transform/index.d.ts +1 -0
  228. package/dist/transform/index.d.ts.map +1 -1
  229. package/dist/transform/index.js +1 -0
  230. package/dist/transform/index.js.map +1 -1
  231. package/dist/transform/model-resolver.d.ts +2 -1
  232. package/dist/transform/model-resolver.d.ts.map +1 -1
  233. package/dist/transform/model-resolver.js +46 -5
  234. package/dist/transform/model-resolver.js.map +1 -1
  235. package/dist/transform/types.d.ts +1 -1
  236. package/dist/transform/types.d.ts.map +1 -1
  237. package/dist/vault-account-source.d.ts +183 -0
  238. package/dist/vault-account-source.d.ts.map +1 -0
  239. package/dist/vault-account-source.js +296 -0
  240. package/dist/vault-account-source.js.map +1 -0
  241. package/dist/vault-enrollment-authority.d.ts +16 -0
  242. package/dist/vault-enrollment-authority.d.ts.map +1 -0
  243. package/dist/vault-enrollment-authority.js +19 -0
  244. package/dist/vault-enrollment-authority.js.map +1 -0
  245. package/dist/vault-family.d.ts +11 -0
  246. package/dist/vault-family.d.ts.map +1 -0
  247. package/dist/vault-family.js +24 -0
  248. package/dist/vault-family.js.map +1 -0
  249. package/dist/vault-provider-state.d.ts +162 -0
  250. package/dist/vault-provider-state.d.ts.map +1 -0
  251. package/dist/vault-provider-state.js +422 -0
  252. package/dist/vault-provider-state.js.map +1 -0
  253. package/package.json +39 -2
@@ -0,0 +1,831 @@
1
+ /**
2
+ * Contract of the Antigravity account repository. The foundation uses the
3
+ * public lease-backed pool store of @cortexkit/common-auth (its `./store`
4
+ * entry). Atomic credential replacement additionally requires a store that
5
+ * exposes the credential-write attribution API described at
6
+ * `AccountRepository.replaceCredential`.
7
+ *
8
+ * The repository replaces whole-file snapshots of `antigravity-accounts.json`
9
+ * with typed operations on individual rows. A row is addressed by a `RowRef`
10
+ * rather than by its position, because positions move under reorder and
11
+ * removal while a ref names one credential of one row: work started for a
12
+ * credential that has since been replaced or removed is refused instead of
13
+ * landing on its successor.
14
+ *
15
+ * Persisted data has four owners:
16
+ * - the store's own roster and credential entries: the bare refresh token,
17
+ * the effective enabled flag and the row order;
18
+ * - provider metadata (`ProviderStateEnvelope`), kept beside the credential
19
+ * in the store's state file. The part of it that describes the signed-in
20
+ * account (see `CREDENTIAL_BOUND_METADATA_FIELDS`) is covered by the
21
+ * store's credential stamp, so a writer that edits it without knowing the
22
+ * stamp makes the value disappear from reads instead of attaching it to
23
+ * the wrong account;
24
+ * - the latest quota reading (`QuotaState`), kept in the row's entry in the
25
+ * store's config file;
26
+ * - account selection (`RoutingSettings`), kept as a plugin settings key in
27
+ * the store's config file.
28
+ *
29
+ * Every shape below that carries `extensions` keeps JSON it does not
30
+ * recognise there, so a file written by a newer build survives a read and
31
+ * rewrite by this one. Optional fields distinguish absent (key missing) from
32
+ * `null`; the codecs never collapse one into the other. Readers treat an
33
+ * optional `null` like absent when they project the data for routing.
34
+ *
35
+ * Credential epochs and identities. The store gives every credential a row
36
+ * holds an epoch number (common-auth `dist/store/attribution.d.ts`,
37
+ * `Attribution`): `add` and `replace` start a new epoch, while refresh and
38
+ * `rotate` keep it. An id that is removed and added again starts past every
39
+ * epoch it held before, in any process. A row without a per-row entry counts
40
+ * as epoch 1. The recorded identity is the account id the provider reported
41
+ * for the credential. Within one epoch it can only go from absent to one
42
+ * value: `recordIdentity`, `rotate`, a re-`add` of the same secret and a
43
+ * refresh all refuse a different identity (`identity-mismatch`, or
44
+ * `identity-contradicted` for a refresh) rather than overwrite it
45
+ * (`dist/store/rows.js` `recordRowIdentity`, `rotateRow`, `addRow`;
46
+ * `dist/store/refresh.d.ts`).
47
+ *
48
+ * Locks. The store takes, in this order and releases in reverse: the row
49
+ * lock `row-<encodeURIComponent(identity ?? id)>` at the state path
50
+ * (`dist/store/runtime.js` `rowLockSpec`), the provider lock (by default
51
+ * `provider-antigravity` at the state path, `dist/store/pool.js`), any extra
52
+ * locks the caller passes, then the `save` locks at the config path and then
53
+ * the state path. A refresh holds the store's `save` locks only while it
54
+ * reads and while it commits, never across the token exchange
55
+ * (`dist/store/refresh.d.ts` `refreshRow`).
56
+ */
57
+ import type { AccountModelFamily, CooldownReason } from './account-types.ts';
58
+ export type JsonPrimitive = string | number | boolean | null;
59
+ export type JsonValue = JsonPrimitive | JsonValue[] | JsonObject;
60
+ export interface JsonObject {
61
+ [key: string]: JsonValue;
62
+ }
63
+ /** Provider name the pool store is opened with; keys its provider-wide lock. */
64
+ export declare const ACCOUNT_STORE_PROVIDER = "antigravity";
65
+ /** Schema version written inside `ProviderStateEnvelope`. */
66
+ export declare const PROVIDER_STATE_SCHEMA_VERSION = 1;
67
+ /** Schema version written inside `QuotaState`. */
68
+ export declare const QUOTA_STATE_SCHEMA_VERSION = 1;
69
+ /** Schema version written inside `RoutingSettings`. */
70
+ export declare const ROUTING_SETTINGS_SCHEMA_VERSION = 1;
71
+ /** Settings key holding `RoutingSettings`. */
72
+ export declare const ROUTING_SETTINGS_KEY = "antigravityRouting";
73
+ /**
74
+ * Settings key holding the `ManagementRecord` of a migration or a multi-row
75
+ * destructive operation. Ordinary row operations never write it.
76
+ */
77
+ export declare const MANAGEMENT_SETTINGS_KEY = "antigravityManagement";
78
+ /** Lock name, at the config path, guarding `MANAGEMENT_SETTINGS_KEY`. */
79
+ export declare const MANAGEMENT_LOCK_NAME = "antigravity-management";
80
+ /**
81
+ * Prefix of the per-account lock passed as a refresh's `providerLock`, in
82
+ * place of the store-wide `provider-antigravity` lock. It must differ from the
83
+ * store's `row-` prefix: the same refresh already holds the row lock, and a
84
+ * provider lock with the same name and path would wait on itself.
85
+ */
86
+ export declare const REFRESH_PROVIDER_LOCK_PREFIX = "agy-refresh-";
87
+ /** Lock name the pre-store writers hold on `antigravity-accounts.json`. */
88
+ export declare const LEGACY_ACCOUNTS_LOCK_NAME = "accounts";
89
+ /** Lease of that lock while the migration holds it. */
90
+ export declare const LEGACY_ACCOUNTS_LOCK_TTL_MS = 10000;
91
+ /**
92
+ * Names one credential of one row: its local id, the credential epoch the
93
+ * store assigned it (1 for a row without a per-row entry) and the identity
94
+ * recorded for it, as explained at the top of this file. Leaving `identity`
95
+ * out means "the row had none recorded", never "any identity". A row's
96
+ * position in the roster is never part of a ref.
97
+ */
98
+ export interface RowRef {
99
+ readonly id: string;
100
+ readonly credentialEpoch: number;
101
+ readonly identity?: string;
102
+ }
103
+ /**
104
+ * A lock file the store takes: its name and directory path plus optional
105
+ * lease tuning. Same shape as `PoolLockSpec` in common-auth
106
+ * `dist/store/refresh-lock.d.ts`, so it can be passed to the store as is.
107
+ */
108
+ export interface AccountLockSpec {
109
+ readonly name: string;
110
+ readonly path: string;
111
+ readonly ttlMs?: number;
112
+ readonly timeoutMs?: number;
113
+ readonly retryMs?: number;
114
+ readonly renew?: boolean;
115
+ readonly renewIntervalMs?: number;
116
+ }
117
+ /**
118
+ * The per-account lock a refresh of `row` passes as its `providerLock` and
119
+ * holds across the token exchange, so refreshes of different accounts run
120
+ * concurrently while two refreshes of one account stay one at a time. It is
121
+ * keyed like the store's row lock (recorded identity, else local id) and
122
+ * URI-encoded so any identity is a safe lock-file name.
123
+ */
124
+ export declare function refreshProviderLock(statePath: string, row: Pick<RowRef, 'id' | 'identity'>): AccountLockSpec;
125
+ /**
126
+ * The lock the pre-store writers hold on `antigravity-accounts.json`, taken
127
+ * while the migration reads or retires that file. It is released before any
128
+ * store call, so it never sits inside the store's lock order.
129
+ */
130
+ export declare function legacyAccountsLock(legacyPath: string): AccountLockSpec;
131
+ export type LastSwitchReason = 'rate-limit' | 'initial' | 'rotation';
132
+ export type FingerprintHistoryReason = 'initial' | 'regenerated' | 'restored';
133
+ export interface StoredClientMetadata {
134
+ ideType: string;
135
+ platform: string;
136
+ pluginType: string;
137
+ extensions?: JsonObject;
138
+ }
139
+ export interface StoredFingerprint {
140
+ deviceId: string;
141
+ sessionToken: string;
142
+ userAgent: string;
143
+ apiClient: string;
144
+ clientMetadata: StoredClientMetadata;
145
+ createdAt: number;
146
+ extensions?: JsonObject;
147
+ }
148
+ export interface StoredFingerprintVersion {
149
+ fingerprint: StoredFingerprint;
150
+ timestamp: number;
151
+ reason: FingerprintHistoryReason;
152
+ extensions?: JsonObject;
153
+ }
154
+ /**
155
+ * Requests sent through the account per model family on one day. `date` is
156
+ * the UTC day the counts belong to (`YYYY-MM-DD`, as
157
+ * `new Date(now).toISOString().slice(0, 10)` gives it). Decoding keeps a
158
+ * past day and its counts as stored; only a usage write starts a new day.
159
+ */
160
+ export interface StoredDailyRequestCounts {
161
+ date: string;
162
+ claude: number;
163
+ gemini: number;
164
+ extensions?: JsonObject;
165
+ }
166
+ /**
167
+ * When each rate limit on the account ends, in epoch milliseconds, keyed by
168
+ * quota pool (`claude`, `gemini-antigravity`, `gemini-cli`) or by a
169
+ * model-specific key; `null` where an older writer stored one. Every key is
170
+ * kept as stored.
171
+ */
172
+ export type StoredRateLimitResetTimes = Record<string, number | null>;
173
+ /**
174
+ * Antigravity metadata kept beside a row's credential; it never holds a
175
+ * credential. The fields named in `CREDENTIAL_BOUND_METADATA_FIELDS`
176
+ * describe the account the credential signs in to (its email, projects,
177
+ * device fingerprint, access verdicts and plan tier), so the store's
178
+ * credential stamp covers them; the rest track how this plugin uses the
179
+ * account.
180
+ */
181
+ export interface ProviderMetadata {
182
+ /** Exactly as received; never case-folded, and never inferred. */
183
+ email?: string | null;
184
+ /** Kept bare here; packed with the refresh token only at host boundaries. */
185
+ projectId?: string | null;
186
+ managedProjectId?: string | null;
187
+ /** Add time shown to the user; the store's own add time is separate. */
188
+ addedAt: number;
189
+ lastUsed: number;
190
+ /**
191
+ * How the pre-store file encoded the enabled flag (absent, true, false or
192
+ * null). The effective flag is the store's own, `value !== false`.
193
+ */
194
+ enabled?: boolean | null;
195
+ lastSwitchReason?: LastSwitchReason | null;
196
+ rateLimitResetTimes?: StoredRateLimitResetTimes | null;
197
+ coolingDownUntil?: number | null;
198
+ cooldownReason?: CooldownReason | null;
199
+ /** Display label; may hold personal data and must stay out of telemetry. */
200
+ label?: string | null;
201
+ fingerprint?: StoredFingerprint | null;
202
+ /** Kept in the stored array order; never re-sorted or truncated. */
203
+ fingerprintHistory?: StoredFingerprintVersion[] | null;
204
+ verificationRequired?: boolean | null;
205
+ verificationRequiredAt?: number | null;
206
+ verificationRequiredReason?: string | null;
207
+ /** Checked where it is captured; kept here as stored. */
208
+ verificationUrl?: string | null;
209
+ /** `true` excludes the row from routing. */
210
+ accountIneligible?: boolean | null;
211
+ accountIneligibleAt?: number | null;
212
+ accountIneligibleReason?: string | null;
213
+ eligibilityStateUpdatedAt?: number | null;
214
+ /** Upstream tier id exactly as reported, never normalised. */
215
+ capturedTierId?: string | null;
216
+ /** As reported; its absence does not mean the account is unpaid or paid. */
217
+ capturedPaidTierId?: string | null;
218
+ capturedTierAt?: number | null;
219
+ capturedTierSchemaVersion?: number | null;
220
+ dailyRequestCounts?: StoredDailyRequestCounts | null;
221
+ extensions?: JsonObject;
222
+ }
223
+ /**
224
+ * The `ProviderMetadata` fields that describe the signed-in account rather
225
+ * than this plugin's use of it. The credential stamp covers exactly these.
226
+ */
227
+ export declare const CREDENTIAL_BOUND_METADATA_FIELDS: readonly ["email", "projectId", "managedProjectId", "fingerprint", "fingerprintHistory", "verificationRequired", "verificationRequiredAt", "verificationRequiredReason", "verificationUrl", "accountIneligible", "accountIneligibleAt", "accountIneligibleReason", "eligibilityStateUpdatedAt", "capturedTierId", "capturedPaidTierId", "capturedTierAt", "capturedTierSchemaVersion"];
228
+ export type CredentialBoundMetadataField = (typeof CREDENTIAL_BOUND_METADATA_FIELDS)[number];
229
+ /**
230
+ * The value the store keeps for a row under the state file's
231
+ * `commonAuthProviderState` key. A newer `schemaVersion` is refused rather
232
+ * than reinterpreted.
233
+ */
234
+ export interface ProviderStateEnvelope {
235
+ schemaVersion: typeof PROVIDER_STATE_SCHEMA_VERSION;
236
+ metadata: ProviderMetadata;
237
+ extensions?: JsonObject;
238
+ }
239
+ export type QuotaWindowName = 'weekly' | '5h';
240
+ export interface StoredQuotaWindow {
241
+ window: QuotaWindowName;
242
+ remainingFraction: number;
243
+ resetTime: string;
244
+ extensions?: JsonObject;
245
+ }
246
+ export interface StoredQuotaGroup {
247
+ /** Exactly as reported; never rounded. */
248
+ remainingFraction?: number | null;
249
+ /** Upstream reset timestamp string, kept as reported. */
250
+ resetTime?: string | null;
251
+ modelCount: number;
252
+ /** Kept in the reported order. */
253
+ windows?: StoredQuotaWindow[] | null;
254
+ extensions?: JsonObject;
255
+ }
256
+ export interface StoredModelQuota {
257
+ modelId: string;
258
+ displayName?: string | null;
259
+ /** Required key; `null` means the model belongs to no group. */
260
+ group: string | null;
261
+ remainingFraction: number;
262
+ resetTime?: string | null;
263
+ extensions?: JsonObject;
264
+ }
265
+ /**
266
+ * The latest quota reading, which the store keeps in the row's config entry.
267
+ * Nothing in it authorises a request: `cachedQuotaAccountId` only records
268
+ * which account produced the reading.
269
+ */
270
+ export interface QuotaState {
271
+ schemaVersion: typeof QUOTA_STATE_SCHEMA_VERSION;
272
+ cachedQuotaAccountId?: string | null;
273
+ cachedQuota?: Record<string, StoredQuotaGroup> | null;
274
+ cachedPerModelQuota?: StoredModelQuota[] | null;
275
+ cachedQuotaUpdatedAt?: number | null;
276
+ extensions?: JsonObject;
277
+ }
278
+ export interface StoredFamilyIndices {
279
+ claude?: number | null;
280
+ gemini?: number | null;
281
+ extensions?: JsonObject;
282
+ }
283
+ export interface StoredFamilyRows {
284
+ claude?: RowRef | null;
285
+ gemini?: RowRef | null;
286
+ extensions?: JsonObject;
287
+ }
288
+ /**
289
+ * Account selection, kept under `ROUTING_SETTINGS_KEY` in the store's config
290
+ * file. The index fields keep the pre-store `activeIndex` and
291
+ * `activeIndexByFamily` values exactly as stored (readers clamp the index to
292
+ * the roster, as the pre-store loader did); the row fields name the selected
293
+ * row for each family independently. A ref that no longer matches a row
294
+ * falls back to the index rules.
295
+ */
296
+ export interface RoutingSettings {
297
+ schemaVersion: typeof ROUTING_SETTINGS_SCHEMA_VERSION;
298
+ activeIndex?: number | null;
299
+ activeIndexByFamily?: StoredFamilyIndices | null;
300
+ activeRow?: RowRef | null;
301
+ activeRowByFamily?: StoredFamilyRows | null;
302
+ extensions?: JsonObject;
303
+ }
304
+ /**
305
+ * What the store tells the provider-state replacement hook about a
306
+ * `replace`. Same shape as `ProviderStateReplacement` in common-auth
307
+ * `dist/store/schema.d.ts`. `previousIdentity` is optional because stores
308
+ * without the locked prior-identity field (0.10.0 among them) never pass it.
309
+ */
310
+ export interface ProviderStateReplacementInfo {
311
+ id: string;
312
+ credentialEpoch: number;
313
+ previousIdentity?: string;
314
+ identity?: string;
315
+ incoming?: unknown;
316
+ }
317
+ /**
318
+ * The hooks the store calls for the value it keeps beside each credential:
319
+ * validation on every load and write, the digest input for the credential
320
+ * stamp, combining a stored value with an incoming one, and the value a
321
+ * credential replacement leaves. Same shape as `ProviderStateCodec` in
322
+ * common-auth `dist/store/schema.d.ts`, where every hook but `validate` is
323
+ * optional.
324
+ */
325
+ export interface ProviderStateCodecContract {
326
+ validate(value: unknown): boolean;
327
+ credentialBound?(value: unknown): unknown;
328
+ merge?(onDisk: unknown, incoming: unknown): unknown;
329
+ onReplace?(previous: unknown | undefined, replacement: ProviderStateReplacementInfo): unknown | undefined;
330
+ }
331
+ /**
332
+ * The provider-state codec this plugin opens the store with: every hook is
333
+ * present. Left out, the store would fall back to its defaults (the incoming
334
+ * value replaces the stored one; a replace keeps only the value handed to
335
+ * it), which would bypass the repository's merge and replacement rules.
336
+ */
337
+ export interface ConfiguredProviderStateCodec extends ProviderStateCodecContract {
338
+ credentialBound(value: unknown): unknown;
339
+ merge(onDisk: unknown, incoming: unknown): unknown;
340
+ onReplace(previous: unknown | undefined, replacement: ProviderStateReplacementInfo): unknown | undefined;
341
+ }
342
+ /** A credential replacement as the replacement policy sees it. */
343
+ export interface ProviderStateReplacement {
344
+ id: string;
345
+ /** The epoch the new credential starts. */
346
+ credentialEpoch: number;
347
+ /**
348
+ * The known prior identity: what the row had recorded before the replace,
349
+ * read by the store under its locks. Absent when the row recorded none or
350
+ * the store does not supply the field (0.10.0 does not). Without a known
351
+ * prior identity a rule cannot conclude that the new credential belongs
352
+ * to the same account, neither from `identity` alone nor from both being
353
+ * absent, so it must not carry the credential-bound account metadata
354
+ * (`CREDENTIAL_BOUND_METADATA_FIELDS`) across on that basis. This is an
355
+ * input to a retention rule only; it is not the attribution check (see
356
+ * `AccountRepository.replaceCredential`).
357
+ */
358
+ previousIdentity?: string;
359
+ /** The identity the replace records for the new credential. */
360
+ identity?: string;
361
+ /** The metadata handed to `replace`, already validated. */
362
+ incoming?: ProviderStateEnvelope;
363
+ }
364
+ /**
365
+ * The repository's rules for combining provider metadata, which the codec
366
+ * factory requires. Both run synchronously under the store's locks and must
367
+ * not call back into the store. A rule that throws refuses the whole write
368
+ * before anything is written.
369
+ */
370
+ export interface ProviderStatePolicy {
371
+ /**
372
+ * Combines the stored metadata with metadata that arrives with a
373
+ * credential write of the same epoch: a refresh, or an `add` of a secret
374
+ * the pool already holds (the store's own `rotate` also calls it).
375
+ */
376
+ merge(onDisk: ProviderStateEnvelope, incoming: ProviderStateEnvelope): ProviderStateEnvelope;
377
+ /**
378
+ * The metadata a row keeps once `replace` gives it a new credential;
379
+ * `undefined` clears it. `previous` is the replaced credential's metadata
380
+ * when the row showed any.
381
+ */
382
+ onReplace(previous: ProviderStateEnvelope | undefined, replacement: ProviderStateReplacement): ProviderStateEnvelope | undefined;
383
+ }
384
+ /**
385
+ * The hooks the store calls for the quota reading: validation, and folding a
386
+ * new reading into the stored one. Same shape as `QuotaCodec` in common-auth
387
+ * `dist/store/schema.d.ts`.
388
+ */
389
+ export interface QuotaCodecContract {
390
+ validate(value: unknown): boolean;
391
+ merge(stored: unknown | undefined, observation: unknown): unknown;
392
+ }
393
+ /**
394
+ * Files the repository owns. The pre-store pool file is read only by the
395
+ * migration, which then retires it; everything else lives in a private
396
+ * directory beside it, so a pre-store writer that still runs can never touch
397
+ * the store's credentials or epochs.
398
+ */
399
+ export interface AccountStorePaths {
400
+ /** The pre-store v4 `antigravity-accounts.json`. */
401
+ legacyPath: string;
402
+ /** `<dirname(legacyPath)>/<basename(legacyPath)>.store/` */
403
+ storeDir: string;
404
+ configPath: string;
405
+ statePath: string;
406
+ migrationPath: string;
407
+ backupsDir: string;
408
+ retiredDir: string;
409
+ transfersDir: string;
410
+ }
411
+ /** What the token exchange is handed: the bare refresh token and the row. */
412
+ export interface AccountTokenExchangeInput {
413
+ refreshToken: string;
414
+ row: AccountRow;
415
+ }
416
+ export interface AccountTokenExchangeResult {
417
+ accessToken: string;
418
+ refreshToken: string;
419
+ expiresAt: number;
420
+ /** Wire identity the provider reported, when it reported one. */
421
+ identity?: string;
422
+ /**
423
+ * Metadata learnt with the new token. Present fields replace the stored
424
+ * ones; omitted fields (projects included) are kept.
425
+ */
426
+ metadata?: Partial<ProviderMetadata>;
427
+ }
428
+ /** Performs one OAuth refresh against the provider. */
429
+ export type AccountTokenExchange = (input: AccountTokenExchangeInput) => Promise<AccountTokenExchangeResult>;
430
+ export interface AccountRepositoryOptions {
431
+ paths: AccountStorePaths;
432
+ /** Clock for evidence times, usage dates and store leases. */
433
+ now: () => number;
434
+ /** Token exchange used by `refresh`. */
435
+ exchange: AccountTokenExchange;
436
+ }
437
+ export type CreateAccountRepository = (options: AccountRepositoryOptions) => AccountRepository;
438
+ /**
439
+ * What the store proves about a row's credential. Same values as
440
+ * `CredentialStampStatus` in common-auth `dist/store/schema.d.ts`; only
441
+ * `bound` is usable, since the store is opened with credential stamps
442
+ * required.
443
+ */
444
+ export type AccountCredentialStamp = 'none' | 'bound' | 'missing' | 'malformed' | 'mismatched' | 'legacy';
445
+ export interface AccountCredentialView {
446
+ /** Bare refresh token; never packed with project ids here. */
447
+ refreshToken: string;
448
+ accessToken?: string;
449
+ expiresAt?: number;
450
+ }
451
+ /**
452
+ * The provider metadata a row shows. `dropped` means the state file holds a
453
+ * value the row does not show (another writer changed its account-describing
454
+ * part, or the codec refuses it); callers treat that as an error to surface,
455
+ * never as an empty value to regenerate.
456
+ */
457
+ export type AccountMetadataView = {
458
+ status: 'present';
459
+ metadata: ProviderMetadata;
460
+ } | {
461
+ status: 'absent';
462
+ } | {
463
+ status: 'dropped';
464
+ reason: 'uncovered' | 'invalid';
465
+ };
466
+ export type AccountQuotaView = {
467
+ status: 'present';
468
+ quota: QuotaState;
469
+ } | {
470
+ status: 'absent';
471
+ };
472
+ export interface AccountRow {
473
+ ref: RowRef;
474
+ /** Position in the roster; presentation only. */
475
+ index: number;
476
+ /** The store's effective enabled flag. */
477
+ enabled: boolean;
478
+ disabledReason?: string;
479
+ /** When the store admitted the row; not the user-visible add time. */
480
+ storeAddedAt?: number;
481
+ credential?: AccountCredentialView;
482
+ /** May be refreshed, pulled for, or routed to. */
483
+ usable: boolean;
484
+ stamp: AccountCredentialStamp;
485
+ torn?: true;
486
+ unbound?: true;
487
+ invalid?: 'roster' | 'entry';
488
+ metadata: AccountMetadataView;
489
+ quota: AccountQuotaView;
490
+ }
491
+ export type ManagementKind = 'migration' | 'clear' | 'replace-pool';
492
+ /**
493
+ * A multi-row operation in progress. Admission refuses new work while one is
494
+ * pending; work already admitted finishes. `targets` are row ids, and
495
+ * `progress` names the last durable step, so a restarted process resumes
496
+ * instead of repeating it.
497
+ */
498
+ export interface ManagementRecord {
499
+ id: string;
500
+ kind: ManagementKind;
501
+ targets: readonly string[];
502
+ progress: {
503
+ step: string;
504
+ completedTargets: readonly string[];
505
+ };
506
+ }
507
+ export type AccountRepositoryRead = {
508
+ status: 'ready';
509
+ rows: readonly AccountRow[];
510
+ routing?: RoutingSettings;
511
+ } | {
512
+ status: 'pending-migration';
513
+ } | {
514
+ status: 'management-pending';
515
+ management: ManagementRecord;
516
+ } | {
517
+ status: 'error';
518
+ file: 'config' | 'state' | 'settings';
519
+ reason: string;
520
+ };
521
+ /**
522
+ * What a metadata mutator asks for. Clearing is explicit, so a mutator that
523
+ * forgets to return a value never deletes the row's metadata.
524
+ */
525
+ export type MetadataUpdate = {
526
+ kind: 'set';
527
+ metadata: ProviderMetadata;
528
+ } | {
529
+ kind: 'keep';
530
+ } | {
531
+ kind: 'clear';
532
+ };
533
+ /**
534
+ * A transition mutator may also decline, for example when the metadata it is
535
+ * shown records evidence newer than the evidence the caller acts on; nothing
536
+ * is written, the enabled flag included.
537
+ */
538
+ export type MetadataTransition = MetadataUpdate | {
539
+ kind: 'decline';
540
+ };
541
+ /**
542
+ * Runs under the row and store locks with a private copy of the current
543
+ * metadata (undefined when the row shows none). It must not call back into
544
+ * the repository.
545
+ */
546
+ export type MetadataMutator = (current: ProviderMetadata | undefined, row: AccountRow) => MetadataUpdate | Promise<MetadataUpdate>;
547
+ export type MetadataTransitionMutator = (current: ProviderMetadata | undefined, row: AccountRow) => MetadataTransition | Promise<MetadataTransition>;
548
+ export interface AccountLoginInput {
549
+ /** A fresh UUID for a new row; the result names the row actually used. */
550
+ id: string;
551
+ /** Bare refresh token. */
552
+ refreshToken: string;
553
+ /** Authenticated wire identity, when the login established one. */
554
+ identity?: string;
555
+ metadata: ProviderMetadata;
556
+ }
557
+ export interface AccountLoginResult {
558
+ /** Authoritative: an existing row's ref when the secret was already held. */
559
+ ref: RowRef;
560
+ /**
561
+ * `rotated` when the pool already held this secret: the retry keeps that
562
+ * row's credential epoch.
563
+ */
564
+ outcome: 'added' | 'added-disabled' | 'completed' | 'rotated';
565
+ }
566
+ export interface AccountReplaceInput {
567
+ refreshToken: string;
568
+ identity?: string;
569
+ metadata?: ProviderMetadata;
570
+ /**
571
+ * Whether a disabled row stays disabled after the new credential lands.
572
+ * OpenCode 1 keeps the user's choice; other hosts decide their own policy.
573
+ */
574
+ disabled: 'keep' | 'enable';
575
+ }
576
+ export type AccountRefreshOutcome = {
577
+ status: 'rotated';
578
+ ref: RowRef;
579
+ accessToken: string;
580
+ expiresAt: number;
581
+ } | {
582
+ /**
583
+ * The provider answered for another account. The successor is kept,
584
+ * disabled and bound to the expected identity, and no bearer is handed
585
+ * out until a validated `replaceCredential`.
586
+ */
587
+ status: 'identity-contradicted';
588
+ ref: RowRef;
589
+ expectedIdentity: string;
590
+ returnedIdentity: string;
591
+ } | {
592
+ status: 'refused';
593
+ ref: RowRef;
594
+ reason: string;
595
+ };
596
+ export interface AccountRefreshOptions {
597
+ /** Checked before locking, after the locked re-read and at commit. */
598
+ refuse?: (row: AccountRow) => string | undefined | Promise<string | undefined>;
599
+ }
600
+ export interface AccountEnableInput {
601
+ enabled: boolean;
602
+ /** The store's `disabledReason` when disabling. */
603
+ reason?: string;
604
+ /** A user enable refuses an ineligible account; a system one may not. */
605
+ actor: 'user' | 'system';
606
+ metadata?: MetadataTransitionMutator;
607
+ }
608
+ /**
609
+ * Evidence about account access, timestamped by when it was observed so a
610
+ * late verdict cannot undo a newer one.
611
+ */
612
+ export type AccessVerdict = {
613
+ kind: 'verification-required';
614
+ observedAt: number;
615
+ reason?: string;
616
+ verificationUrl?: string;
617
+ } | {
618
+ kind: 'ineligible';
619
+ observedAt: number;
620
+ reason: string;
621
+ } | {
622
+ kind: 'cleared';
623
+ observedAt: number;
624
+ enable: boolean;
625
+ };
626
+ export interface AccountTransitionResult {
627
+ ref: RowRef;
628
+ declined?: true;
629
+ metadataOutcome?: 'updated' | 'cleared' | 'unchanged';
630
+ metadata?: ProviderMetadata;
631
+ }
632
+ export interface AccountMetadataResult {
633
+ ref: RowRef;
634
+ outcome: 'updated' | 'cleared' | 'unchanged';
635
+ metadata?: ProviderMetadata;
636
+ }
637
+ export interface ProjectObservation {
638
+ projectId?: string | null;
639
+ managedProjectId?: string | null;
640
+ }
641
+ export interface FingerprintObservation {
642
+ fingerprint: StoredFingerprint;
643
+ history: readonly StoredFingerprintVersion[];
644
+ }
645
+ export interface TierObservation {
646
+ observedAt: number;
647
+ tierId: string | null;
648
+ paidTierId: string | null;
649
+ schemaVersion: number;
650
+ }
651
+ export type CooldownObservation = {
652
+ until: number;
653
+ reason: CooldownReason;
654
+ } | null;
655
+ export interface UsageObservation {
656
+ family: AccountModelFamily;
657
+ at: number;
658
+ }
659
+ export interface AccountUsageResult {
660
+ ref: RowRef;
661
+ lastUsed: number;
662
+ dailyRequestCounts: StoredDailyRequestCounts;
663
+ }
664
+ /** Which selection `selectAccount` changes. */
665
+ export type RoutingTarget = 'active' | AccountModelFamily;
666
+ export interface ManagementReceipt {
667
+ management: ManagementRecord;
668
+ outcome: 'completed' | 'pending';
669
+ }
670
+ /**
671
+ * Same failure kinds as `PoolFailureKind` in common-auth
672
+ * `dist/store/errors.d.ts`, followed by the repository's own.
673
+ */
674
+ export type AccountRepositoryFailureKind = 'lock-contention' | 'lock-ownership' | 'pending-migration' | 'load-error' | 'snapshot-contended' | 'publication-sync' | 'publication-incomplete' | 'publication-mismatch' | 'row-staged' | 'credential-exists' | 'unknown-row' | 'invalid-row' | 'invalid-input' | 'id-exists' | 'id-removed' | 'type-mismatch' | 'no-credential' | 'row-disabled' | 'row-protected' | 'duplicate-identity' | 'identity-mismatch' | 'identity-contradicted' | 'endpoint-mismatch' | 'row-key-changed' | 'invalid-order' | 'refresh-stamp-ahead' | 'unbound-credential' | 'attribution' | 'provider' | 'pull' | 'invalid-quota' | 'invalid-provider-state' | 'after-persist-hook' | 'unexpected' | 'management-pending' | 'replacement-unavailable' | 'metadata-dropped' | 'account-ineligible' | 'duplicate-secret' | 'disposed';
675
+ export type AccountRepositoryOperation = 'read' | 'login' | 'replaceCredential' | 'refresh' | 'recordIdentity' | 'setEnabled' | 'recordAccessVerdict' | 'updateMetadata' | 'recordProject' | 'recordFingerprint' | 'recordTier' | 'recordCooldown' | 'recordRateLimits' | 'recordSwitch' | 'recordUsage' | 'recordQuota' | 'selectAccount' | 'reorder' | 'remove' | 'clear' | 'replacePool' | 'flush';
676
+ /**
677
+ * How an operation failed. Messages never contain credentials. `ambiguous`
678
+ * marks a write that may or may not have landed (the usage increment
679
+ * included): callers reload and report instead of replaying it.
680
+ */
681
+ export interface AccountRepositoryFailure {
682
+ operation: AccountRepositoryOperation;
683
+ kind: AccountRepositoryFailureKind;
684
+ retryable: boolean;
685
+ ambiguous: boolean;
686
+ rowId?: string;
687
+ message: string;
688
+ }
689
+ export interface AccountFlushReport {
690
+ /** Writes that completed while draining. */
691
+ completed: number;
692
+ failures: readonly AccountRepositoryFailure[];
693
+ }
694
+ /**
695
+ * Typed operations on the Antigravity account pool.
696
+ *
697
+ * Every operation about an existing credential takes the `RowRef` the
698
+ * caller's evidence was gathered under. The repository refuses it with
699
+ * `attribution` when the row's epoch or recorded identity has changed since
700
+ * then, and with `unknown-row` when the row has been removed. Each method
701
+ * below names the store API that makes this check under the row and save
702
+ * locks before anything is written. Ordinary operations take only the
703
+ * store's locks; only `clear` and `replacePool` write a `ManagementRecord`,
704
+ * the resumable record of a destructive multi-row or migration operation.
705
+ */
706
+ export interface AccountRepository {
707
+ /** Reads the pool and settings without writing or firing quota pulls. */
708
+ read(): Promise<AccountRepositoryRead>;
709
+ /** Resolves once every quota pull fired so far has settled. */
710
+ settled(): Promise<void>;
711
+ /**
712
+ * Admits a login: matches an existing row by exact email, then by secret;
713
+ * contradictory matches refuse. It names no existing credential, so it
714
+ * takes no ref; the returned ref is authoritative.
715
+ */
716
+ login(input: AccountLoginInput): Promise<AccountLoginResult>;
717
+ /**
718
+ * Gives the row in `expected` a new credential and a new epoch
719
+ * (re-authentication). Quota, rate limits, cooldown and access blocks of
720
+ * the old credential are cleared; same-account display fields are kept.
721
+ *
722
+ * The repository must refuse it (`attribution`, nothing written) unless,
723
+ * under the row and save locks and before anything is written, the row
724
+ * still holds exactly `expected`: the same epoch and the same recorded
725
+ * identity, an absent identity matching only an absent one.
726
+ *
727
+ * Requires a store exposing atomic credential-write attribution:
728
+ * `RowWriteOptions.attribution` on `replace` (`dist/store/rows.d.ts`),
729
+ * which common-auth 0.10.0 lacks. The repository passes `expected`'s
730
+ * epoch and identity exactly as that attribution; the store compares them
731
+ * under the row and store locks before completing an interrupted replace,
732
+ * before any write and before the replacement hook, and refuses with
733
+ * `attribution` (retryable, nothing written). Without that API this
734
+ * method has no conforming implementation. The hook's `previousIdentity`
735
+ * is only an input to the retention rule, never this check.
736
+ */
737
+ replaceCredential(expected: RowRef, input: AccountReplaceInput): Promise<{
738
+ ref: RowRef;
739
+ }>;
740
+ /**
741
+ * Exchanges the row's refresh token for a new access token (and possibly
742
+ * a new refresh token). The epoch names the login or replacement that put
743
+ * the credential there, not each refresh, so a refresh keeps it; metadata
744
+ * the exchange leaves out (projects included) is kept. This is the only
745
+ * path by which a successor of an existing credential reaches the store.
746
+ *
747
+ * The row lock and the per-account lock from `refreshProviderLock` are
748
+ * held across the exchange; the save locks are held only while the store
749
+ * reads the row and while it commits the files. The store calls
750
+ * `refuse(row)` before locking, on the locked re-read and at commit
751
+ * (`dist/store/refresh.d.ts`); the repository refuses there when the
752
+ * row's epoch or identity differs from `ref`, and the store then drops the
753
+ * refreshed token instead of committing it to a changed or replaced row.
754
+ */
755
+ refresh(ref: RowRef, options?: AccountRefreshOptions): Promise<AccountRefreshOutcome>;
756
+ /**
757
+ * Records an authenticated identity lookup for the credential in `ref`.
758
+ * Fence: the store's `recordIdentity` attribution checks the epoch; a
759
+ * different identity already recorded refuses with `identity-mismatch`.
760
+ */
761
+ recordIdentity(ref: RowRef, identity: string): Promise<{
762
+ ref: RowRef;
763
+ }>;
764
+ /**
765
+ * Enables or disables a row, optionally changing its metadata in the same
766
+ * crash-consistent write. Fence: the store's `enable`/`disable`
767
+ * `attribution` option (epoch and identity).
768
+ */
769
+ setEnabled(ref: RowRef, input: AccountEnableInput): Promise<AccountTransitionResult>;
770
+ /**
771
+ * Applies access evidence (verification, eligibility) together with the
772
+ * enabled flag. Fence: as `setEnabled`.
773
+ */
774
+ recordAccessVerdict(ref: RowRef, verdict: AccessVerdict): Promise<AccountTransitionResult>;
775
+ /**
776
+ * Changes metadata only; the credential and its stamp status stay. Fence
777
+ * for this and every metadata `record*` method below: the store's
778
+ * `updateProviderState` fence (epoch and identity).
779
+ */
780
+ updateMetadata(ref: RowRef, mutator: MetadataMutator): Promise<AccountMetadataResult>;
781
+ recordProject(ref: RowRef, observation: ProjectObservation): Promise<AccountMetadataResult>;
782
+ recordFingerprint(ref: RowRef, observation: FingerprintObservation): Promise<AccountMetadataResult>;
783
+ recordTier(ref: RowRef, observation: TierObservation): Promise<AccountMetadataResult>;
784
+ recordCooldown(ref: RowRef, observation: CooldownObservation): Promise<AccountMetadataResult>;
785
+ /**
786
+ * Merges reset times key by key, keeping the later time for each key.
787
+ */
788
+ recordRateLimits(ref: RowRef, resets: Readonly<StoredRateLimitResetTimes>): Promise<AccountMetadataResult>;
789
+ recordSwitch(ref: RowRef, reason: LastSwitchReason): Promise<AccountMetadataResult>;
790
+ /**
791
+ * Adds one request for the family to the account's count for the current
792
+ * UTC day (from the injected clock), starting from zero when the stored
793
+ * `date` is another day, and keeps the later of the stored and given
794
+ * `lastUsed`. It runs under the row lock. A failure that leaves unknown
795
+ * whether the increment landed is reported as `ambiguous` and is never
796
+ * retried, so a request is never counted twice.
797
+ */
798
+ recordUsage(ref: RowRef, observation: UsageObservation): Promise<AccountUsageResult>;
799
+ /**
800
+ * Records a quota reading for the credential in `ref`, separately from
801
+ * `recordTier`: the two are independent writes. Fence: the store's
802
+ * `recordQuota` attribution (epoch and identity).
803
+ */
804
+ recordQuota(ref: RowRef, observation: QuotaState): Promise<void>;
805
+ /** Points a selection at a row (`null` clears it) in the routing settings. */
806
+ selectAccount(target: RoutingTarget, row: RowRef | null): Promise<void>;
807
+ /** Sets the roster order; `ids` names every row exactly once. */
808
+ reorder(ids: readonly string[]): Promise<void>;
809
+ /**
810
+ * Removes one row; the store keeps its epochs retired, so a later add of
811
+ * the same id starts past them. Fence: the store's `remove` `protect`
812
+ * callback, which sees the row under every lock before anything is
813
+ * written.
814
+ */
815
+ remove(ref: RowRef): Promise<void>;
816
+ /** Removes every row as one journaled operation. */
817
+ clear(): Promise<ManagementReceipt>;
818
+ /**
819
+ * Replaces the account list through the store's single configuration write.
820
+ * Prepared accounts remain disabled until that write commits. Refresh tokens
821
+ * stay in an owner-only transfer file until verification; interrupted calls
822
+ * replay the recorded write plan. If the store cannot publish the entire list
823
+ * at once, replacement of a non-empty pool refuses without changing it.
824
+ */
825
+ replacePool(inputs: readonly AccountLoginInput[]): Promise<ManagementReceipt>;
826
+ /** Waits for queued writes and reports every failure among them. */
827
+ flush(): Promise<AccountFlushReport>;
828
+ /** Flushes, then refuses further writes (`disposed`). */
829
+ dispose(): Promise<AccountFlushReport>;
830
+ }
831
+ //# sourceMappingURL=account-repository-types.d.ts.map