@cortexkit/anthropic-auth-core 1.23.0 → 2.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 (134) hide show
  1. package/README.md +2 -0
  2. package/dist/accounts.d.ts +3 -16
  3. package/dist/cachekeep.d.ts +9 -0
  4. package/dist/claude-code.d.ts +16 -0
  5. package/dist/claustrum-enrollment.d.ts +2 -0
  6. package/dist/claustrum-scoped-roster.d.ts +4 -0
  7. package/dist/claustrum-scoped-runtime.d.ts +3 -0
  8. package/dist/claustrum-scoped.d.ts +14 -0
  9. package/dist/claustrum.d.ts +0 -209
  10. package/dist/commands/account.d.ts +2 -3
  11. package/dist/index.d.ts +44 -1
  12. package/dist/index.js +29700 -38
  13. package/dist/internal-types/LICENSE +21 -0
  14. package/dist/internal-types/commands/builtins.d.ts +71 -0
  15. package/dist/internal-types/commands/index.d.ts +10 -0
  16. package/dist/internal-types/commands/menu.d.ts +61 -0
  17. package/dist/internal-types/commands/model.d.ts +238 -0
  18. package/dist/internal-types/commands/pi.d.ts +23 -0
  19. package/dist/internal-types/commands/seam.d.ts +72 -0
  20. package/dist/internal-types/fs/refresh-file-lock.d.ts +33 -0
  21. package/dist/internal-types/logger/capture-sink.d.ts +14 -0
  22. package/dist/internal-types/logger/engine.d.ts +100 -0
  23. package/dist/internal-types/logger/index.d.ts +6 -0
  24. package/dist/internal-types/logger/redact.d.ts +11 -0
  25. package/dist/internal-types/pi-slot/index.d.ts +3 -0
  26. package/dist/internal-types/pi-slot/slot.d.ts +49 -0
  27. package/dist/internal-types/quota/codec.d.ts +11 -0
  28. package/dist/internal-types/quota/format.d.ts +46 -0
  29. package/dist/internal-types/quota/index.d.ts +10 -0
  30. package/dist/internal-types/quota/map.d.ts +63 -0
  31. package/dist/internal-types/quota/merge.d.ts +48 -0
  32. package/dist/internal-types/quota/projection.d.ts +64 -0
  33. package/dist/internal-types/store/attribution.d.ts +28 -0
  34. package/dist/internal-types/store/errors.d.ts +55 -0
  35. package/dist/internal-types/store/hooks.d.ts +12 -0
  36. package/dist/internal-types/store/identity.d.ts +39 -0
  37. package/dist/internal-types/store/index.d.ts +21 -0
  38. package/dist/internal-types/store/mutate.d.ts +189 -0
  39. package/dist/internal-types/store/pool.d.ts +196 -0
  40. package/dist/internal-types/store/provider-state.d.ts +131 -0
  41. package/dist/internal-types/store/publication.d.ts +47 -0
  42. package/dist/internal-types/store/pull.d.ts +36 -0
  43. package/dist/internal-types/store/refresh-lock.d.ts +63 -0
  44. package/dist/internal-types/store/refresh.d.ts +72 -0
  45. package/dist/internal-types/store/rows.d.ts +313 -0
  46. package/dist/internal-types/store/runtime.d.ts +36 -0
  47. package/dist/internal-types/store/schema.d.ts +443 -0
  48. package/dist/internal-types/store/settings.d.ts +63 -0
  49. package/dist/internal-types/store/torn.d.ts +78 -0
  50. package/dist/migration-source.d.ts +33 -0
  51. package/dist/models.d.ts +41 -0
  52. package/dist/native-account-runtime.d.ts +121 -0
  53. package/dist/native-account-view.d.ts +126 -0
  54. package/dist/native-command-effects.d.ts +59 -0
  55. package/dist/native-credential-validation.d.ts +42 -0
  56. package/dist/native-custody-activation.d.ts +45 -0
  57. package/dist/native-custody.d.ts +114 -0
  58. package/dist/native-enrollment-authority.d.ts +2 -0
  59. package/dist/native-host-auth-read.d.ts +3 -0
  60. package/dist/native-host-auth-write.d.ts +51 -0
  61. package/dist/native-host-auth.d.ts +12 -0
  62. package/dist/native-local-credential-service.d.ts +76 -0
  63. package/dist/native-local-runtime-readers.d.ts +22 -0
  64. package/dist/native-lock-observer.d.ts +12 -0
  65. package/dist/native-menu-executor.d.ts +243 -0
  66. package/dist/native-menu-model.d.ts +142 -0
  67. package/dist/native-migration-proof.d.ts +28 -0
  68. package/dist/native-migration-source.d.ts +47 -0
  69. package/dist/native-migration.d.ts +66 -0
  70. package/dist/native-quota-codec.d.ts +32 -0
  71. package/dist/native-refresh-coordinator.d.ts +240 -0
  72. package/dist/native-roster-seed.d.ts +115 -0
  73. package/dist/native-runtime-registry.d.ts +19 -0
  74. package/dist/native-runtime.d.ts +204 -0
  75. package/dist/native-transient-account.d.ts +38 -0
  76. package/dist/native-ui.d.ts +45 -0
  77. package/dist/native-usage-publication.d.ts +11 -0
  78. package/dist/native-vault-admission.d.ts +8 -0
  79. package/dist/native-vault-connection.d.ts +33 -0
  80. package/dist/native-vault-paths.d.ts +13 -0
  81. package/dist/native-vault-runtime.d.ts +102 -0
  82. package/dist/native-vault-seed.d.ts +16 -0
  83. package/dist/pool-authority.d.ts +159 -0
  84. package/dist/pool-binding.d.ts +32 -0
  85. package/dist/pool-paths.d.ts +21 -0
  86. package/dist/pool-store.d.ts +32 -0
  87. package/dist/provider-error.d.ts +139 -0
  88. package/dist/quota-manager.d.ts +18 -7
  89. package/dist/relay.d.ts +14 -1
  90. package/dist/request-history.d.ts +34 -0
  91. package/dist/sse.d.ts +81 -0
  92. package/dist/sticky-routing.d.ts +27 -0
  93. package/package.json +9 -4
  94. package/dist/accounts.js +0 -3881
  95. package/dist/auth.js +0 -185
  96. package/dist/cache1h.js +0 -97
  97. package/dist/cachekeep-registry.js +0 -124
  98. package/dist/cachekeep.js +0 -604
  99. package/dist/cch.js +0 -172
  100. package/dist/claude-code.js +0 -403
  101. package/dist/claustrum-enrollment-registry.d.ts +0 -17
  102. package/dist/claustrum-enrollment-registry.js +0 -194
  103. package/dist/claustrum-enrollment.js +0 -485
  104. package/dist/claustrum-scoped-roster.js +0 -194
  105. package/dist/claustrum-scoped-runtime.js +0 -230
  106. package/dist/claustrum-scoped.js +0 -193
  107. package/dist/claustrum.js +0 -1471
  108. package/dist/commands/account.js +0 -368
  109. package/dist/constants.js +0 -83
  110. package/dist/custom-headers.js +0 -102
  111. package/dist/dump.js +0 -616
  112. package/dist/fast.js +0 -66
  113. package/dist/json.js +0 -10
  114. package/dist/killswitch.js +0 -132
  115. package/dist/logger.js +0 -288
  116. package/dist/logging.js +0 -59
  117. package/dist/mid-conversation-output-config.js +0 -89
  118. package/dist/model-remap.js +0 -72
  119. package/dist/models.js +0 -177
  120. package/dist/network-errors.js +0 -27
  121. package/dist/oauth-profile.js +0 -60
  122. package/dist/pkce.js +0 -17
  123. package/dist/prime.js +0 -841
  124. package/dist/provider.js +0 -0
  125. package/dist/quota-header-feed.js +0 -331
  126. package/dist/quota-headers.js +0 -121
  127. package/dist/quota-manager.js +0 -856
  128. package/dist/quotas.js +0 -141
  129. package/dist/relay.js +0 -1303
  130. package/dist/routing.js +0 -94
  131. package/dist/start.js +0 -29
  132. package/dist/sticky-routing.js +0 -541
  133. package/dist/thinking-binding.js +0 -54
  134. package/dist/token-fingerprint.js +0 -8
@@ -0,0 +1,121 @@
1
+ import { type PoolCredential } from "./internal-types/store/index.js";
2
+ import { type OAuthAccountProfile, type OAuthQuotaSnapshot, type PrimeUsageDelta } from './accounts.ts';
3
+ import { type LogLevel } from './logger.ts';
4
+ import { type NativeAccountMetadataPatch, type NativeAccountSnapshot, type NativeAccountView } from './native-account-view.ts';
5
+ import { type NativeCustodyReceipt } from './native-custody.ts';
6
+ import { type NativeLocalCredentialServiceOptions } from './native-local-credential-service.ts';
7
+ import type { NativeLocalExternalPolicy } from './native-local-runtime-readers.ts';
8
+ import type { NativeKnownCredentialSubject, NativeRefreshResult, NativeRefreshSubject } from './native-refresh-coordinator.ts';
9
+ import { type NativeDisplayProfile, type NativeVaultRuntime, type NativeVaultRuntimeOptions } from './native-vault-runtime.ts';
10
+ import { type NativeLocalPoolBinding } from './pool-binding.ts';
11
+ import type { NativePoolPaths } from './pool-paths.ts';
12
+ import type { QuotaRequestDispatch } from './quota-manager.ts';
13
+ import type { RelayConfig } from './relay.ts';
14
+ export type { NativeAccountMetadataPatch, NativeAccountSnapshot, NativeAccountView, } from './native-account-view.ts';
15
+ export interface NativeAccountRuntimeOptions {
16
+ paths: NativePoolPaths;
17
+ host: 'opencode' | 'pi';
18
+ /** The opencode-anthropic-auth setup command rechecks that hosts are stopped before credential-file writes, so migration cannot change credentials used by a running host. */
19
+ beforePoolWrite?: () => Promise<void>;
20
+ local?: Partial<Pick<NativeLocalCredentialServiceOptions, 'refreshToken' | 'resolveIdentity' | 'failurePolicy' | 'now'>>;
21
+ vault?: Omit<NativeVaultRuntimeOptions, 'paths' | 'host'>;
22
+ }
23
+ export interface NativeLocalAuthorizeOptions {
24
+ intent?: 'serve' | 'refresh';
25
+ rejectedAccessToken?: string;
26
+ signal?: AbortSignal;
27
+ policy?: (account: NativeAccountView, snapshot: NativeAccountSnapshot) => NativeLocalExternalPolicy;
28
+ }
29
+ export interface NativeAccountWriteInput {
30
+ routeId: string;
31
+ credential: PoolCredential;
32
+ accountIdentity?: string;
33
+ label?: string;
34
+ replace?: boolean;
35
+ }
36
+ export interface NativeApiSubject {
37
+ kind: 'api';
38
+ binding: NativeLocalPoolBinding;
39
+ credentialFingerprint: string;
40
+ baseURL: string;
41
+ authHeader?: 'authorization-bearer' | 'x-api-key';
42
+ }
43
+ export type NativeRelayUpdate = Partial<Omit<RelayConfig, 'token'>> & {
44
+ token?: string | null;
45
+ };
46
+ export interface NativeAccountRuntime {
47
+ readonly vault: NativeVaultRuntime;
48
+ /** Fresh private relay authorization for transport only; never include it in a status snapshot. */
49
+ getRelayConfig(): Promise<RelayConfig | null>;
50
+ updateRelay(patch: NativeRelayUpdate): Promise<void>;
51
+ read(): Promise<NativeAccountSnapshot>;
52
+ authorizeLocal(routeId: string, options?: NativeLocalAuthorizeOptions): Promise<NativeRefreshResult>;
53
+ authorizeApi(routeId: string, signal?: AbortSignal): Promise<{
54
+ type: 'api';
55
+ apiKey: string;
56
+ baseURL: string;
57
+ authHeader?: 'authorization-bearer' | 'x-api-key';
58
+ subject: NativeApiSubject;
59
+ }>;
60
+ authorizeVault(routeId: string, signal?: AbortSignal): Promise<NativeCustodyReceipt>;
61
+ loginOAuth(input: {
62
+ routeId: string;
63
+ credential: {
64
+ access: string;
65
+ refresh: string;
66
+ expires: number;
67
+ };
68
+ accountIdentity?: string;
69
+ label?: string;
70
+ replace?: boolean;
71
+ }): Promise<NativeAccountView>;
72
+ putAccount(input: NativeAccountWriteInput): Promise<NativeAccountView>;
73
+ addApi(input: {
74
+ routeId?: string;
75
+ apiKey: string;
76
+ baseURL?: string;
77
+ authHeader?: 'authorization-bearer' | 'x-api-key';
78
+ label?: string;
79
+ replace?: boolean;
80
+ }): Promise<NativeAccountView>;
81
+ updateSettings(mutator: (settings: Record<string, unknown>) => Record<string, unknown> | undefined | Promise<Record<string, unknown> | undefined>): Promise<{
82
+ settings: Record<string, unknown>;
83
+ outcome: 'updated' | 'unchanged';
84
+ }>;
85
+ /**
86
+ * Store `level` as the logging level, then make it this process's live
87
+ * logger level if it is not already, even when the stored value was
88
+ * unchanged. Nothing is applied when the write fails.
89
+ */
90
+ setLoggingLevel(level: LogLevel): Promise<void>;
91
+ setEnabled(routeId: string, enabled: boolean): Promise<void>;
92
+ remove(routeId: string): Promise<void>;
93
+ /**
94
+ * `movedRouteId` names the account the caller moved; it identifies the
95
+ * account in the change's INFO log and does not affect the order written.
96
+ */
97
+ reorder(routeIds: readonly string[], movedRouteId?: string): Promise<void>;
98
+ captureLocalSubject(routeId: string): Promise<NativeRefreshSubject>;
99
+ publishLocal(subject: NativeKnownCredentialSubject, patch: NativeAccountMetadataPatch): Promise<boolean>;
100
+ publishApi(subject: NativeApiSubject, patch: {
101
+ lastUsed: number;
102
+ }): Promise<boolean>;
103
+ resetBackoff(routeId: string, fence: NativeRefreshSubject | NativeCustodyReceipt, kind?: 'refresh' | 'quota' | 'all'): Promise<boolean>;
104
+ getOrCreateAuthLineage(routeId: string, fence: NativeKnownCredentialSubject | NativeCustodyReceipt): Promise<string | undefined>;
105
+ incrementPrimeUsage(routeId: string, fence: NativeKnownCredentialSubject | NativeCustodyReceipt, delta?: PrimeUsageDelta): Promise<boolean>;
106
+ fetchQuota(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal, dispatch?: QuotaRequestDispatch): Promise<OAuthQuotaSnapshot>;
107
+ fetchProfile(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<OAuthAccountProfile>;
108
+ /** Like fetchProfile, but returns before the profile is saved; see NativeDisplayProfile. */
109
+ fetchProfileForDisplay(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<NativeDisplayProfile>;
110
+ close(): void;
111
+ }
112
+ /** Host instances own leases, while stores and the vault connection live until the last release. */
113
+ export declare function acquireNativeAccountRuntime(options: NativeAccountRuntimeOptions): NativeAccountRuntime;
114
+ /** Evaluate quota and killswitch policy for this caller's model, outside shared credential refresh work. */
115
+ export declare function nativeAccountPolicy(account: NativeAccountView, snapshot: NativeAccountSnapshot, modelId?: string): NativeLocalExternalPolicy;
116
+ /** The local migration journal records completed transfer from host credentials and sidecars to the credential pool. Local use refuses without that record. Host vault enrollment instead selects independent settings and metadata, leaving local credentials, journal and metadata untouched. */
117
+ export declare function createNativeAccountRuntime(options: NativeAccountRuntimeOptions): NativeAccountRuntime;
118
+ export declare function primeDelta(delta: PrimeUsageDelta): {
119
+ inputTokens: number;
120
+ outputTokens: number;
121
+ };
@@ -0,0 +1,126 @@
1
+ import { type PoolRow } from "./internal-types/store/index.js";
2
+ import { type AccountOperationError, type AccountStorage, type OAuthAccountProfile, type OAuthQuotaSnapshot, type PrimeUsageCounters } from './accounts.ts';
3
+ import type { NativeVaultRosterDocument } from './native-roster-seed.ts';
4
+ import type { NativeRuntimeEntry, NativeRuntimeState } from './native-runtime.ts';
5
+ import type { NativeVaultRoutingSeed } from './native-vault-seed.ts';
6
+ import { type NativeLocalPoolBinding } from './pool-binding.ts';
7
+ import type { NativePoolPaths } from './pool-paths.ts';
8
+ /** Display and policy metadata, not evidence that a presented token was accepted for this account. */
9
+ export interface NativeAccountView {
10
+ id: string;
11
+ type: 'oauth' | 'api';
12
+ source: 'local' | 'vault';
13
+ enabled: boolean;
14
+ label?: string;
15
+ addedAt?: number;
16
+ accountIdentity?: string;
17
+ binding?: NativeLocalPoolBinding;
18
+ credentialId?: string;
19
+ state?: string;
20
+ quota?: OAuthQuotaSnapshot;
21
+ profile?: OAuthAccountProfile;
22
+ prime?: PrimeUsageCounters;
23
+ lastUsed?: number;
24
+ lastRefreshedAt?: number;
25
+ lastRefreshError?: AccountOperationError;
26
+ lastQuotaRefreshError?: AccountOperationError;
27
+ quotaErrorClearedAt?: number;
28
+ quotaErrorGeneration?: number;
29
+ refreshErrorClearedAt?: number;
30
+ baseURL?: string;
31
+ authHeader?: 'authorization-bearer' | 'x-api-key';
32
+ }
33
+ /**
34
+ * One-line status text for an account's state, shared by host status
35
+ * displays. A local account in 'unsupported-access' holds a saved access value
36
+ * that is not a Claude OAuth access token; it is never sent to Claude or
37
+ * refreshed, so the text names the remedy. Other states, such as vault
38
+ * credential states, are shown as recorded. Returns '' when there is no state.
39
+ */
40
+ export declare function formatNativeAccountState(view: Pick<NativeAccountView, 'state'>): string;
41
+ export interface NativeAccountSnapshot {
42
+ mode: 'local' | 'claustrum';
43
+ settings: Record<string, unknown>;
44
+ accounts: NativeAccountView[];
45
+ /** Vault session-to-account assignments use this separate file. Local mode keeps the assignment file at the destination recorded by migration. */
46
+ routingPath?: string;
47
+ routingSeed?: NativeVaultRoutingSeed;
48
+ /** AccountStorage-shaped input for pure policy predicates, never a credential or persistence authority. */
49
+ policyStorage: AccountStorage;
50
+ }
51
+ export interface NativeAccountMetadataPatch {
52
+ quota?: OAuthQuotaSnapshot;
53
+ profile?: OAuthAccountProfile;
54
+ lastUsed?: number;
55
+ lastQuotaRefreshError?: AccountOperationError;
56
+ quotaErrorClearedAt?: number;
57
+ quotaErrorGeneration?: number;
58
+ prime?: PrimeUsageCounters;
59
+ authLineageId?: string;
60
+ }
61
+ /** Copy data without invoking caller getters, proxies, serializers or callbacks. */
62
+ export declare function captureNativePlainData(input: unknown): unknown;
63
+ export declare function captureNativeMetadataPatch(patch: NativeAccountMetadataPatch): NativeAccountMetadataPatch;
64
+ export declare function applyNativeMetadataPatch(entry: NativeRuntimeEntry, patch: NativeAccountMetadataPatch): NativeRuntimeEntry;
65
+ /** Keep established retry policy without persisting provider bodies or arbitrary exception text. */
66
+ export declare function nativeQuotaFailure(error: unknown, accountIdentity: string | undefined, checkedAt: number, previous?: AccountOperationError): AccountOperationError | undefined;
67
+ export declare class NativeAccountReadError extends Error {
68
+ readonly status?: number | undefined;
69
+ readonly retryAfter?: number | undefined;
70
+ readonly code?: 'ECONNRESET' | undefined;
71
+ constructor(status?: number | undefined, retryAfter?: number | undefined, code?: 'ECONNRESET' | undefined);
72
+ }
73
+ /** Keep the HTTP status and retry classification. Omit provider error text and nested causes because they can contain credentials. */
74
+ export declare function nativeAccountReadError(error: unknown, responseStatus?: number): NativeAccountReadError;
75
+ export declare const NATIVE_PRIMARY_CREDENTIAL_ID = "oauth:anthropic";
76
+ export interface NativeVaultPrimaryPin {
77
+ routeId: string;
78
+ credentialId: string;
79
+ accountIdentity: string;
80
+ }
81
+ /** Vault discovery saves the default credential ID, route ID and verified account UUID in vault settings. Readers compare that UUID to the current roster so a replaced default cannot inherit another account's metadata. */
82
+ export declare function nativeVaultPrimaryPin(settings: Record<string, unknown>): NativeVaultPrimaryPin | undefined;
83
+ export declare function nativeVaultPrimaryRow(roster: NativeVaultRosterDocument | undefined, pin: NativeVaultPrimaryPin | undefined): {
84
+ readonly routeId: string;
85
+ readonly credentialId: string;
86
+ readonly credentialType: 'oauth' | 'api_key';
87
+ readonly accountIdentity?: string;
88
+ readonly aliases?: readonly string[];
89
+ readonly state: string;
90
+ readonly label: string;
91
+ readonly email?: string;
92
+ readonly orgName?: string;
93
+ readonly enabled: boolean;
94
+ readonly addedAt: number;
95
+ readonly quota?: unknown;
96
+ readonly stale?: true;
97
+ readonly unclaimed?: true;
98
+ } | undefined;
99
+ export declare function nativeAccountSettings(settings: Record<string, unknown>): Record<string, unknown>;
100
+ /**
101
+ * Whether a local OAuth row is held back only because another writer is part
102
+ * way through saving it, for example a refresh that has written the state
103
+ * file naming the row's first account UUID but not yet the config file.
104
+ *
105
+ * True only when the row is torn and would otherwise be an enabled,
106
+ * coherent candidate: it holds a credential, is not disabled (including
107
+ * quarantine and duplicate-identity disables), staged, invalid or unbound,
108
+ * and its stamp is bound to that credential. Such a row is shown enabled but
109
+ * without a binding: it may be chosen for a request, and local authorization
110
+ * then waits for the write to finish before it can serve.
111
+ *
112
+ * A different stored credential epoch can belong to a replacement. Keep
113
+ * the existing refusal for mismatched epochs rather than use old metadata
114
+ * as evidence that this write only learns the account's first UUID.
115
+ */
116
+ export declare function nativeLocalRowAwaitsTornWrite(paths: NativePoolPaths, row: PoolRow, stored?: NativeRuntimeEntry): boolean;
117
+ /** `nativeLocalRowAwaitsTornWrite` for the row a route id names, mapped as the account projection maps it. */
118
+ export declare function nativeLocalRouteAwaitsTornWrite(paths: NativePoolPaths, rows: readonly PoolRow[], settings: Record<string, unknown>, routeId: string, runtime?: NativeRuntimeState): boolean;
119
+ /** Join quota, profile and errors only for matching storage, account and credential generation; a reused route must not expose its previous account. */
120
+ export declare function projectNativeAccountViews(input: {
121
+ paths: NativePoolPaths;
122
+ rows: readonly PoolRow[];
123
+ settings: Record<string, unknown>;
124
+ runtime?: NativeRuntimeState;
125
+ roster?: NativeVaultRosterDocument;
126
+ }): NativeAccountSnapshot;
@@ -0,0 +1,59 @@
1
+ import { type LogLevel } from './logger.ts';
2
+ /**
3
+ * In-process effects of a committed native account or settings change.
4
+ *
5
+ * NativeAccountRuntime calls these logging and live-level helpers after its
6
+ * write has been committed. Account
7
+ * and settings effects follow only from what that write changed, so every
8
+ * host's /claude actions emit the same INFO records, and a refused or failed
9
+ * write has no effect. The one exception to "unchanged means no effect" is the
10
+ * explicit logging-level command (NativeAccountRuntime.setLoggingLevel): when
11
+ * its stored level is already the requested one, it still sets this process's
12
+ * live logger level if that differs. Payloads carry account ids, labels and
13
+ * setting values only, never credential material.
14
+ */
15
+ type Settings = Record<string, unknown>;
16
+ /** The setting values whose changes have effects, read before a settings mutator can edit its copy. */
17
+ export interface NativeSettingsEffectFields {
18
+ killswitchEnabled: boolean;
19
+ killswitchMain: Record<string, number> | undefined;
20
+ killswitchAccounts: Record<string, Record<string, number>> | undefined;
21
+ logLevel: string | undefined;
22
+ }
23
+ export declare function captureNativeSettingsEffectFields(settings: Settings): NativeSettingsEffectFields;
24
+ /**
25
+ * Log the killswitch and logging-level changes between the settings before a
26
+ * committed write and the settings that write left on disk, then apply a
27
+ * changed stored logging level to this process's logger. Threshold changes
28
+ * are compared and logged through the numeric projection only.
29
+ */
30
+ export declare function applyCommittedNativeSettingsEffects(before: NativeSettingsEffectFields, committed: Settings): void;
31
+ /**
32
+ * Make `level` this process's live logger level when it is not already, and
33
+ * record the change. The INFO record is emitted before the new level is
34
+ * applied, so it is filtered by the level in force until then: changing from
35
+ * info to warn leaves the record in the log, while changing from warn or error
36
+ * to info emits none. Returns whether the live level changed.
37
+ */
38
+ export declare function applyNativeLogLevel(level: LogLevel): boolean;
39
+ export type NativeAccountChange = 'account enabled' | 'account disabled' | 'account removed' | 'account reordered';
40
+ /**
41
+ * Log one committed change to an account, identified by its account id and
42
+ * label. A reorder whose caller did not say which account it moved is logged
43
+ * without an id.
44
+ */
45
+ export declare function logCommittedNativeAccountChange(change: NativeAccountChange, account: {
46
+ id?: string;
47
+ label?: string;
48
+ }): void;
49
+ /**
50
+ * Log an account that a committed add created. The payload holds the account
51
+ * id, its label and the credential kind ('apikey' or 'oauth'); it never holds
52
+ * the credential, its base URL or its auth header.
53
+ */
54
+ export declare function logCommittedNativeAccountAdded(account: {
55
+ id: string;
56
+ label?: string;
57
+ type: 'oauth' | 'api';
58
+ }): void;
59
+ export {};
@@ -0,0 +1,42 @@
1
+ import { type NativeLocalPoolBinding } from './pool-binding.ts';
2
+ /**
3
+ * The access-token fingerprint, expiry and last recorded refresh time identify
4
+ * the captured credentials. No bearer material is stored.
5
+ */
6
+ export interface NativeLocalCredentialVersion {
7
+ readonly accessFingerprint: string;
8
+ readonly expires: number;
9
+ readonly lastRefreshedAt?: number;
10
+ }
11
+ /**
12
+ * Positive local account evidence belongs to its own binding, not merely to
13
+ * the runtime entry containing it. Copying an entry must not transfer evidence
14
+ * to another row, storage location, credential epoch or account identity.
15
+ * This evidence does not establish freshness or eligibility to serve.
16
+ */
17
+ export interface NativeLocalCredentialValidation {
18
+ readonly binding: NativeLocalPoolBinding & {
19
+ readonly identity: string;
20
+ };
21
+ /** Common-auth's full SHA-256 of `oauth\0` followed by the refresh token. */
22
+ readonly credentialFingerprint: string;
23
+ readonly version: NativeLocalCredentialVersion;
24
+ }
25
+ /**
26
+ * Core publishes this local input type so consumers do not need common-auth
27
+ * declarations.
28
+ */
29
+ export interface NativeLocalCredentialMaterial {
30
+ readonly type: string;
31
+ readonly access?: string;
32
+ readonly refresh?: string;
33
+ readonly expires?: number;
34
+ readonly lastRefreshedAt?: number;
35
+ }
36
+ /** Validate the closed, token-free proof schema; no defaults or I/O are used. */
37
+ export declare function isNativeLocalCredentialValidation(value: unknown): value is NativeLocalCredentialValidation;
38
+ /**
39
+ * Match only the captured binding and exact OAuth material. Expired material
40
+ * can still match evidence; serving freshness is a separate decision.
41
+ */
42
+ export declare function nativeLocalCredentialValidationMatches(validation: unknown, binding: NativeLocalPoolBinding, material: NativeLocalCredentialMaterial | undefined): boolean;
@@ -0,0 +1,45 @@
1
+ import type { NativeCustodyInventory } from './native-custody.ts';
2
+ import { type NativeHostAuthWriteHooks } from './native-host-auth-write.ts';
3
+ import { type NativeMigrationJournal } from './pool-authority.ts';
4
+ import type { NativePoolPaths } from './pool-paths.ts';
5
+ import { createNativePoolStore } from './pool-store.ts';
6
+ export type NativeCustodyActivationErrorCode = 'migration-required' | 'invalid-state' | 'primary-missing' | 'primary-mismatch' | 'primary-unverified' | 'primary-conflict' | 'row-unverified' | 'unenrolled-local-row' | 'vault-ambiguous' | 'roster-conflict' | 'runtime-conflict' | 'settings-conflict' | 'credential-changed' | 'host-auth-changed' | 'consent-required' | 'migration-busy' | 'ownership-lost' | 'auth-content-refused' | 'process-fence-refused' | 'migration-proof-changed';
7
+ export declare class NativeCustodyActivationError extends Error {
8
+ readonly code: NativeCustodyActivationErrorCode;
9
+ constructor(code: NativeCustodyActivationErrorCode);
10
+ }
11
+ export interface NativeCustodyActivationOptions {
12
+ paths: NativePoolPaths;
13
+ host: 'opencode' | 'pi';
14
+ env: NodeJS.ProcessEnv;
15
+ /** Rejects unless every selected host is stopped and inspection succeeded. */
16
+ processFence: () => Promise<void>;
17
+ /**
18
+ * The user's explicit consent to delete a stored Pi Anthropic OAuth entry.
19
+ * It never authorizes deleting a Pi API key, which always refuses.
20
+ */
21
+ removePiAnthropicAuth: boolean;
22
+ /**
23
+ * Lists the vault accounts this host's enrollment token may read; called
24
+ * only while preparing the activation.
25
+ */
26
+ discover: () => Promise<NativeCustodyInventory>;
27
+ }
28
+ export interface NativeCustodyActivationHooks {
29
+ /**
30
+ * Test hook for simulated crashes and lease loss. Receives a label naming
31
+ * the activation step about to run or just finished, never account data.
32
+ */
33
+ onStep?: (step: string) => Promise<void>;
34
+ hostWrite?: NativeHostAuthWriteHooks;
35
+ store?: Pick<Parameters<typeof createNativePoolStore>[0], 'onStep' | 'onLockStep'>;
36
+ }
37
+ export type NativeCustodyActivationResult = {
38
+ status: 'already-vault';
39
+ journal: NativeMigrationJournal;
40
+ } | {
41
+ status: 'committed';
42
+ journal: NativeMigrationJournal;
43
+ };
44
+ /** Offline, crash-forward switch of a retired local pool to vault custody. */
45
+ export declare function runNativeCustodyActivation(options: NativeCustodyActivationOptions, hooks?: NativeCustodyActivationHooks): Promise<NativeCustodyActivationResult>;
@@ -0,0 +1,114 @@
1
+ /** Claustrum IPC operations for listing accounts, reading tokens, reporting rejection, and closing the connection. */
2
+ export interface NativeCustodyClient {
3
+ listScoped: (enrollmentToken?: string) => Promise<{
4
+ readonly view: string;
5
+ readonly rows: readonly {
6
+ readonly id: string;
7
+ readonly categories: readonly string[];
8
+ readonly credentialType: string;
9
+ readonly serves: readonly string[];
10
+ readonly providerIds: readonly string[];
11
+ readonly authMethod?: 'apikey' | 'chatgpt' | 'antigravity' | 'oauth';
12
+ readonly refreshAdapter?: string;
13
+ readonly state: string;
14
+ readonly recordVersion: number;
15
+ readonly operations: readonly string[];
16
+ readonly createdAtMs: number | null;
17
+ readonly accountId?: string;
18
+ readonly email?: string;
19
+ readonly orgName?: string;
20
+ }[];
21
+ }>;
22
+ getScoped: (input: {
23
+ credentialId: string;
24
+ enrollmentToken?: string;
25
+ minTtlMs?: number;
26
+ }) => Promise<{
27
+ material: string;
28
+ recordVersion: number;
29
+ expiresAtMs: number | null;
30
+ credentialId?: string;
31
+ projectId?: string;
32
+ accountId?: string;
33
+ email?: string;
34
+ orgName?: string;
35
+ }>;
36
+ reportAuthFailureScoped: (input: {
37
+ credentialId: string;
38
+ enrollmentToken?: string;
39
+ providerStatus: number;
40
+ recordVersion: number;
41
+ reporterSource: NativeCustodyReporterSource;
42
+ }) => Promise<void>;
43
+ close: () => void;
44
+ }
45
+ export type NativeCustodyReporterSource = 'direct' | 'relay_status_field' | 'relay_message_parse';
46
+ export interface NativeCustodyLogger {
47
+ warn: (message: string, data?: unknown) => void;
48
+ debug: (message: string, data?: unknown) => void;
49
+ }
50
+ export interface NativeCustodyOptions {
51
+ host: 'opencode' | 'pi';
52
+ connect: () => Promise<NativeCustodyClient>;
53
+ readToken?: () => Promise<{
54
+ token: string;
55
+ token_generation: number;
56
+ }>;
57
+ env?: NodeJS.ProcessEnv;
58
+ now?: () => number;
59
+ logger?: NativeCustodyLogger;
60
+ }
61
+ export interface NativeCustodyIdentity {
62
+ readonly credentialId: string;
63
+ readonly accountIdentity: string;
64
+ }
65
+ /** A common-auth receipt: retain its original object identity and non-enumerable accessToken. */
66
+ export interface NativeCustodyReceipt {
67
+ readonly credentialId: string;
68
+ readonly credentialType: 'oauth';
69
+ readonly accountIdentity?: string;
70
+ readonly accountIdentitySource: 'asserted' | 'parsed' | 'expected' | 'none';
71
+ readonly expectedAccountIdentity?: string;
72
+ readonly assertedCredentialId?: string;
73
+ readonly assertedAccountIdentity?: string;
74
+ readonly recordVersion: number;
75
+ readonly expiresAtMs: number | null;
76
+ readonly accessToken: string;
77
+ }
78
+ export interface NativeCustodyInventory {
79
+ readonly view: string;
80
+ readonly credentials: readonly {
81
+ readonly credentialId: string;
82
+ readonly credentialType: 'oauth' | 'api_key';
83
+ readonly accountIdentity?: string;
84
+ readonly state: string;
85
+ readonly email?: string;
86
+ readonly orgName?: string;
87
+ }[];
88
+ readonly skipped: readonly {
89
+ readonly credentialId?: string;
90
+ readonly reason: 'empty credential id' | 'duplicate credential id' | 'blank account identity' | 'empty state';
91
+ }[];
92
+ }
93
+ export type NativeCustodyErrorCode = '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';
94
+ export declare class NativeCustodyError extends Error {
95
+ readonly code: NativeCustodyErrorCode;
96
+ constructor(code: NativeCustodyErrorCode);
97
+ }
98
+ export type NativeCustodyRetry = {
99
+ retry: true;
100
+ receipt: NativeCustodyReceipt;
101
+ } | {
102
+ retry: false;
103
+ reason: 'reauthorize-failed' | 'credential-changed' | 'account-changed' | 'version-not-newer';
104
+ code?: NativeCustodyErrorCode;
105
+ };
106
+ export interface NativeCustody {
107
+ discover: (signal?: AbortSignal) => Promise<NativeCustodyInventory>;
108
+ authorize: (identity: NativeCustodyIdentity, signal?: AbortSignal) => Promise<NativeCustodyReceipt>;
109
+ reportFailure: (receipt: NativeCustodyReceipt, status: number, reporterSource: NativeCustodyReporterSource) => Promise<void>;
110
+ prepareRetry: (served: NativeCustodyReceipt, signal?: AbortSignal) => Promise<NativeCustodyRetry>;
111
+ close: () => void;
112
+ }
113
+ /** Share a lazy Claustrum connection; each authorize call reads a fresh enrollment token and OAuth receipt. */
114
+ export declare function createNativeCustody(options: NativeCustodyOptions): NativeCustody;
@@ -0,0 +1,2 @@
1
+ /** Enrollment files, not account settings, choose the host's credential source. */
2
+ export declare function readNativeEnrollmentMode(host: 'opencode' | 'pi', env?: NodeJS.ProcessEnv): Promise<'local' | 'claustrum'>;
@@ -0,0 +1,3 @@
1
+ import { type NativeHostAuthEntryInspection } from './native-host-auth.ts';
2
+ /** Read only the host's login classification; credentials and source fingerprints never leave this boundary. */
3
+ export declare function readNativeHostAuthKind(host: 'opencode' | 'pi', path: string): Promise<NativeHostAuthEntryInspection['kind']>;
@@ -0,0 +1,51 @@
1
+ export interface NativeHostAuthWriteInput {
2
+ readonly host: 'opencode' | 'pi';
3
+ /**
4
+ * Use the configured auth path, not a symlink's target, so the source reader
5
+ * can reject a symlink at the auth file. Its directory must already exist.
6
+ */
7
+ readonly authPath: string;
8
+ readonly sourceDigest: string;
9
+ readonly expectedDigest: string;
10
+ readonly env: NodeJS.ProcessEnv;
11
+ readonly removePiAnthropicAuth: boolean;
12
+ /**
13
+ * Must reject if the caller no longer owns the offline operation.
14
+ * Awaited immediately before replacing or deleting the auth file.
15
+ */
16
+ readonly processFence: () => Promise<void>;
17
+ }
18
+ export interface NativeHostAuthWriteHooks {
19
+ readonly beforeRecheck?: () => Promise<void>;
20
+ readonly beforeRename?: () => Promise<void>;
21
+ readonly afterRename?: () => Promise<void>;
22
+ readonly afterUnlink?: () => Promise<void>;
23
+ }
24
+ export type NativeHostAuthWriteOutcome = {
25
+ readonly status: 'unchanged';
26
+ } | {
27
+ readonly status: 'replaced' | 'created';
28
+ } | {
29
+ readonly status: 'removed';
30
+ readonly file: 'replaced' | 'unlinked';
31
+ };
32
+ export declare class NativeHostAuthWriteError extends Error {
33
+ readonly code: 'invalid-source' | 'unsafe-source' | 'consent-required' | 'process-fence-refused' | 'write-io' | 'hook-failed';
34
+ /** Records the file change already completed if a later callback throws. */
35
+ readonly effect: NativeHostAuthWriteOutcome | undefined;
36
+ constructor(code: 'invalid-source' | 'unsafe-source' | 'consent-required' | 'process-fence-refused' | 'write-io' | 'hook-failed',
37
+ /** Records the file change already completed if a later callback throws. */
38
+ effect?: NativeHostAuthWriteOutcome | undefined);
39
+ }
40
+ /** Match this helper's temporary filenames so crash cleanup leaves other files alone. */
41
+ export declare function isNativeHostAuthWriteStagingName(name: string): boolean;
42
+ /**
43
+ * Write only the selected host's auth file; do not advance a migration journal.
44
+ * The caller checks Anthropic's entry digest when resuming migration. This write
45
+ * also rechecks the complete file to retain other providers' current entries.
46
+ * There is no compare-and-swap: a host write after the final check can still be
47
+ * overwritten by our rename or unlink. Advisory locks do not stop that writer.
48
+ * Before calling, verify the selected hosts are stopped and that their auth paths
49
+ * match the migration's captured paths. On resume, check Anthropic's entry again.
50
+ */
51
+ export declare function writeNativeHostAuth(input: NativeHostAuthWriteInput, hooks?: NativeHostAuthWriteHooks): Promise<NativeHostAuthWriteOutcome>;
@@ -0,0 +1,12 @@
1
+ export declare class NativeHostAuthError extends Error {
2
+ readonly code: 'invalid-source' | 'supervised-auth-snapshot';
3
+ constructor(code: 'invalid-source' | 'supervised-auth-snapshot');
4
+ }
5
+ export declare function hasSupervisedAuthContentSnapshot(env: NodeJS.ProcessEnv): boolean;
6
+ export declare function requireNoSupervisedAuthContentSnapshot(env: NodeJS.ProcessEnv): void;
7
+ export interface NativeHostAuthEntryInspection {
8
+ readonly kind: 'absent' | 'oauth' | 'api' | 'api_key' | 'activation';
9
+ readonly digest: string;
10
+ }
11
+ /** Inspect parsed host auth only; path safety, consent and writes belong to callers. */
12
+ export declare function inspectNativeHostAuthEntry(host: 'opencode' | 'pi', hostAuth: unknown): Readonly<NativeHostAuthEntryInspection>;