@cortexkit/anthropic-auth-core 2.0.2 → 2.0.3

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 (52) hide show
  1. package/dist/accounts.d.ts +7 -1
  2. package/dist/cache1h.d.ts +2 -0
  3. package/dist/cachekeep-registry.d.ts +3 -0
  4. package/dist/dump.d.ts +2 -0
  5. package/dist/fast.d.ts +2 -0
  6. package/dist/index.d.ts +9 -4
  7. package/dist/index.js +27333 -25202
  8. package/dist/internal-types/auth-menu/terminal.d.ts +43 -0
  9. package/dist/internal-types/claustrum/consumer.d.ts +132 -0
  10. package/dist/internal-types/claustrum/custody.d.ts +178 -0
  11. package/dist/internal-types/claustrum/enrollment.d.ts +164 -0
  12. package/dist/internal-types/claustrum/errors.d.ts +16 -0
  13. package/dist/internal-types/claustrum/host-slot.d.ts +39 -0
  14. package/dist/internal-types/claustrum/index.d.ts +19 -0
  15. package/dist/internal-types/claustrum/insula.d.ts +69 -0
  16. package/dist/internal-types/claustrum/interlock.d.ts +27 -0
  17. package/dist/internal-types/claustrum/roster.d.ts +221 -0
  18. package/dist/internal-types/fs/refresh-file-lock.d.ts +8 -2
  19. package/dist/internal-types/quota/format.d.ts +26 -0
  20. package/dist/internal-types/quota/index.d.ts +2 -2
  21. package/dist/internal-types/routing/admission.d.ts +93 -0
  22. package/dist/internal-types/routing/index.d.ts +8 -0
  23. package/dist/internal-types/routing/ordered.d.ts +47 -0
  24. package/dist/internal-types/routing/pins.d.ts +22 -0
  25. package/dist/internal-types/routing/sticky.d.ts +158 -0
  26. package/dist/internal-types/setup/command-error.d.ts +17 -0
  27. package/dist/internal-types/setup/command.d.ts +3 -0
  28. package/dist/internal-types/setup/detect.d.ts +6 -0
  29. package/dist/internal-types/setup/index.d.ts +6 -0
  30. package/dist/internal-types/setup/process-fence.d.ts +43 -0
  31. package/dist/internal-types/setup/register.d.ts +11 -0
  32. package/dist/internal-types/setup/types.d.ts +138 -0
  33. package/dist/internal-types/store/pool.d.ts +1 -1
  34. package/dist/internal-types/store/refresh-lock.d.ts +0 -1
  35. package/dist/logging.d.ts +2 -0
  36. package/dist/mid-conversation-output-config.d.ts +35 -0
  37. package/dist/native-account-runtime.d.ts +6 -2
  38. package/dist/native-account-view.d.ts +19 -3
  39. package/dist/native-custody-activation.d.ts +1 -1
  40. package/dist/native-menu-executor.d.ts +1 -1
  41. package/dist/native-migration.d.ts +25 -4
  42. package/dist/native-quota-observations.d.ts +26 -0
  43. package/dist/native-transient-account.d.ts +3 -4
  44. package/dist/native-ui.d.ts +2 -0
  45. package/dist/native-usage-publication.d.ts +5 -0
  46. package/dist/native-vault-runtime.d.ts +4 -0
  47. package/dist/network-errors.d.ts +1 -0
  48. package/dist/pool-authority.d.ts +25 -7
  49. package/dist/pool-paths.d.ts +2 -0
  50. package/dist/quotas.d.ts +15 -2
  51. package/dist/relay.d.ts +20 -0
  52. package/package.json +2 -2
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Keeps the Pi install refusal message stable while exposing safe process details.
3
+ * A clipped tail can start inside a credential, so discard its first line—or
4
+ * the whole tail if it has no newline—before redacting.
5
+ */
6
+ export declare class SetupCommandError extends Error {
7
+ readonly step = "pi-install";
8
+ readonly exitCode: number | null;
9
+ readonly signal: string | null;
10
+ readonly stderrTail: string;
11
+ constructor(details: {
12
+ exitCode: number | null;
13
+ signal: string | null;
14
+ stderrTail: string;
15
+ stderrTruncated?: boolean;
16
+ });
17
+ }
@@ -0,0 +1,3 @@
1
+ import type { SetupIO, SetupPlugin, SetupResult } from './types.js';
2
+ export declare const AMBIGUOUS_OPENCODE_MESSAGE = "Multiple OpenCode generations found. Choose --opencode=1|2|both before running noninteractive setup.";
3
+ export declare function runSetup(plugin: SetupPlugin, argv?: readonly string[], io?: SetupIO): Promise<SetupResult>;
@@ -0,0 +1,6 @@
1
+ import type { SetupDetection, SetupFileSystem, SetupIO, SetupPlugin } from './types.js';
2
+ export declare const defaultSetupFileSystem: SetupFileSystem;
3
+ export declare function findExecutableOnPath(name: string, io?: SetupIO): string | null;
4
+ export declare function openCodeDesktopMarkers(io?: SetupIO): string[];
5
+ export declare function detectOpenCodeGeneration(io?: SetupIO): '1' | '2' | 'ambiguous';
6
+ export declare function detectHosts(plugin: SetupPlugin, io?: SetupIO): Promise<SetupDetection>;
@@ -0,0 +1,6 @@
1
+ export { AMBIGUOUS_OPENCODE_MESSAGE, runSetup } from './command.js';
2
+ export { SetupCommandError } from './command-error.js';
3
+ export { detectHosts, detectOpenCodeGeneration, findExecutableOnPath, openCodeDesktopMarkers, } from './detect.js';
4
+ export { assertHostsStopped, createProcessFence, listSetupProcesses, ProcessFenceViolationError, ProcessInspectionError, type ProcessInspectionStep, } from './process-fence.js';
5
+ export { type PlannedWrite, planOpenCodeRegistration, registerOpenCode, registerPi, updatePluginConfig, } from './register.js';
6
+ export type { CommandResult, CommandRunner, HostDetection, OpenCodeGeneration, ProcessFence, SetupCallbackContext, SetupDetection, SetupEnvironment, SetupFileSystem, SetupHost, SetupIO, SetupPlugin, SetupResult, } from './types.js';
@@ -0,0 +1,43 @@
1
+ import type { CommandRunner, ProcessFence, SetupEnvironment } from './types.js';
2
+ export interface ProcessInspectionStep {
3
+ step: 'tasklist' | 'CIM' | 'ps';
4
+ exitCode: number | null;
5
+ signal: NodeJS.Signals | null;
6
+ timedOut: boolean;
7
+ durationMs: number;
8
+ }
9
+ export declare class ProcessInspectionError extends Error implements ProcessInspectionStep {
10
+ readonly code = "process-inspection-failed";
11
+ readonly step: ProcessInspectionStep['step'];
12
+ readonly exitCode: number | null;
13
+ readonly signal: NodeJS.Signals | null;
14
+ readonly timedOut: boolean;
15
+ readonly durationMs: number;
16
+ constructor(details: ProcessInspectionStep);
17
+ get refusalText(): string;
18
+ }
19
+ export declare class ProcessFenceViolationError extends Error {
20
+ readonly activeHosts: Array<{
21
+ pid: number;
22
+ command: string;
23
+ }>;
24
+ constructor(activeHosts: Array<{
25
+ pid: number;
26
+ command: string;
27
+ }>);
28
+ }
29
+ /** List processes before filtering hosts; Windows PID 0 is a valid idle-process row. */
30
+ export declare function listSetupProcesses(runner?: CommandRunner, options?: {
31
+ platform?: string;
32
+ env?: SetupEnvironment;
33
+ onStep?: (details: ProcessInspectionStep) => void;
34
+ /** False skips the Windows PowerShell query for Node and Bun command lines. */
35
+ inspectRuntimes?: boolean;
36
+ }): Promise<Array<{
37
+ pid: number;
38
+ command: string;
39
+ }>>;
40
+ export declare function createProcessFence(runner?: CommandRunner, options?: {
41
+ platform?: string;
42
+ }): ProcessFence;
43
+ export declare function assertHostsStopped(fence: ProcessFence, env?: SetupEnvironment): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import type { OpenCodeGeneration, SetupIO, SetupPlugin } from './types.js';
2
+ export interface PlannedWrite {
3
+ path: string;
4
+ content: string;
5
+ changed: boolean;
6
+ }
7
+ /** Edit only array entries so unrelated JSONC text, including comments, survives. */
8
+ export declare function updatePluginConfig(text: string, key: 'plugin' | 'plugins', pkg: string, version: string): string;
9
+ export declare function planOpenCodeRegistration(plugin: SetupPlugin, generation: OpenCodeGeneration, io?: SetupIO): PlannedWrite[];
10
+ export declare function registerOpenCode(writes: readonly PlannedWrite[], beforeWrite?: () => Promise<void>): Promise<void>;
11
+ export declare function registerPi(plugin: SetupPlugin, executable: string, io?: SetupIO): Promise<void>;
@@ -0,0 +1,138 @@
1
+ import type { MenuTerminal } from '../auth-menu/terminal.js';
2
+ import type { ClaustrumEnrollmentConnection, hostEnrollmentPaths } from '../claustrum/index.js';
3
+ export type SetupHost = 'opencode' | 'pi';
4
+ export type OpenCodeGeneration = '1' | '2' | 'both';
5
+ export type SetupEnvironment = Record<string, string | undefined>;
6
+ /**
7
+ * What setup decided before calling a plugin callback. The OpenCode generation
8
+ * is the one being registered, after `--opencode` or the interactive choice, so
9
+ * a plugin can sign in the way that generation expects (OpenCode 2 does not
10
+ * read OpenCode 1's login file).
11
+ */
12
+ export interface SetupCallbackContext {
13
+ opencodeGeneration: OpenCodeGeneration;
14
+ mode: 'local' | 'claustrum';
15
+ /**
16
+ * Every host this run sets up, in order, so the first `beforeSignIn` can
17
+ * check conditions across all of them (for example that their storage paths
18
+ * do not overlap) before any host is changed.
19
+ */
20
+ hosts: readonly SetupHost[];
21
+ /**
22
+ * Pi's agent folder, resolved the way Pi itself does (`PI_CODING_AGENT_DIR`,
23
+ * with `~` expanded, else `~/.pi/agent`). Pi's own `auth.json` lives here;
24
+ * use it rather than a plugin path setting, which can point elsewhere.
25
+ */
26
+ piAgentDir: string;
27
+ }
28
+ /** Provider login, credential migration and vault activation stay in plugin callbacks. */
29
+ export interface SetupPlugin {
30
+ packages: {
31
+ opencode: string;
32
+ pi: string;
33
+ };
34
+ version: string;
35
+ displayName: string;
36
+ slashCommand: string;
37
+ vault: {
38
+ connectionFile: string;
39
+ hosts: Record<SetupHost, {
40
+ name: string;
41
+ paths: Parameters<typeof hostEnrollmentPaths>[0];
42
+ }>;
43
+ };
44
+ /**
45
+ * Runs for each host on a real run after the host, mode and generation are
46
+ * chosen and before the vault ceremony or `signInLocal`, while nothing has
47
+ * changed yet. Rejecting stops setup for that host, so a plugin can ask for
48
+ * consent or check preconditions before any credential or authority change.
49
+ */
50
+ beforeSignIn?(host: SetupHost, context: SetupCallbackContext): Promise<void>;
51
+ signInLocal(host: SetupHost, context: SetupCallbackContext): Promise<void>;
52
+ migrate(host: SetupHost, context: SetupCallbackContext): Promise<void>;
53
+ /** Reject mixed local/vault credentials and activate provider-specific vault access before registration. */
54
+ beforeRegister?(host: SetupHost, mode: 'local' | 'claustrum', context: SetupCallbackContext): Promise<void>;
55
+ }
56
+ export interface CommandResult {
57
+ exitCode: number;
58
+ stdout: string;
59
+ stderr: string;
60
+ spawnError?: boolean;
61
+ stderrTruncated?: boolean;
62
+ signal?: NodeJS.Signals | null;
63
+ timedOut?: boolean;
64
+ durationMs?: number;
65
+ }
66
+ export interface CommandRunner {
67
+ run(file: string, args: readonly string[], options?: {
68
+ env?: SetupEnvironment;
69
+ timeoutMs?: number;
70
+ windowsVerbatimArguments?: boolean;
71
+ }): Promise<CommandResult>;
72
+ }
73
+ export interface SetupFileSystem {
74
+ exists(path: string): boolean;
75
+ isDirectory(path: string): boolean;
76
+ isFile(path: string): boolean;
77
+ isExecutable(path: string): boolean;
78
+ readText(path: string): string;
79
+ realpath(path: string): string;
80
+ }
81
+ export interface ProcessFence {
82
+ listRunningHosts(env?: SetupEnvironment): Promise<Array<{
83
+ pid: number;
84
+ command: string;
85
+ }>>;
86
+ /**
87
+ * For a dry run, which must change nothing: the hosts found without starting
88
+ * any program that writes files. On Windows that skips the PowerShell query
89
+ * for Node and Bun command lines (PowerShell writes a startup cache into the
90
+ * user's profile), so Node or Bun processes are only counted. A fence without
91
+ * it is previewed with `listRunningHosts`.
92
+ */
93
+ previewRunningHosts?(env?: SetupEnvironment): Promise<{
94
+ hosts: Array<{
95
+ pid: number;
96
+ command: string;
97
+ }>;
98
+ uncheckedRuntimes: number;
99
+ }>;
100
+ }
101
+ /** Defaults use the process terminal and environment; overrides are test seams. */
102
+ export interface SetupIO {
103
+ terminal?: MenuTerminal;
104
+ env?: SetupEnvironment;
105
+ platform?: string;
106
+ home?: string;
107
+ cwd?: string;
108
+ fs?: SetupFileSystem;
109
+ runner?: CommandRunner;
110
+ fence?: ProcessFence;
111
+ connect?: (options: {
112
+ connectionFile: string;
113
+ handshakeTimeoutMs: number;
114
+ }) => Promise<ClaustrumEnrollmentConnection>;
115
+ wait?: (ms: number) => Promise<void>;
116
+ }
117
+ export interface HostDetection {
118
+ installed: boolean;
119
+ executable: string | null;
120
+ version: string | null;
121
+ directory: string;
122
+ }
123
+ export interface SetupDetection {
124
+ opencode: HostDetection & {
125
+ generation: '1' | '2' | 'ambiguous';
126
+ };
127
+ pi: HostDetection;
128
+ claustrum: {
129
+ available: boolean;
130
+ executable: string | null;
131
+ };
132
+ }
133
+ export interface SetupResult {
134
+ hosts: SetupHost[];
135
+ dryRun: boolean;
136
+ mode: 'local' | 'claustrum';
137
+ detection: SetupDetection;
138
+ }
@@ -42,7 +42,7 @@ export interface OpenPoolStoreOptions {
42
42
  requireCredentialStamps?: boolean;
43
43
  /** Require an exact secret fingerprint for every roster-publication removal. */
44
44
  requireRemovedFingerprint?: boolean;
45
- /** Injected clock for leases, refresh stamps and `addedAt`. */
45
+ /** Logical clock for refresh stamps and `addedAt`; filesystem leases always use wall time. */
46
46
  now?: () => number;
47
47
  /**
48
48
  * Ordered store-lock list held across every read-modify-write. Defaults to
@@ -24,7 +24,6 @@ export type LockEvent = {
24
24
  path: string;
25
25
  };
26
26
  export interface LockEnvironment {
27
- now: () => number;
28
27
  onLockEvent?: (event: LockEvent) => void;
29
28
  onLockStep?: (lock: {
30
29
  name: string;
package/dist/logging.d.ts CHANGED
@@ -12,8 +12,10 @@ export type LoggingCommandAction = {
12
12
  export declare function parseLoggingCommandAction(argumentsText: string): LoggingCommandAction;
13
13
  export declare function buildLoggingStatusSummary(input?: {
14
14
  level?: LogLevel;
15
+ settingsPath?: string;
15
16
  }): string;
16
17
  export declare function executeLoggingCommand(input: {
17
18
  argumentsText: string;
18
19
  level?: LogLevel;
20
+ settingsPath?: string;
19
21
  }): string;
@@ -1,4 +1,11 @@
1
+ /** Per-message effort beta sent with every OAuth Fable 5.1 request. */
1
2
  export declare const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
3
+ /**
4
+ * Per-turn control beta that Claude Code sends on every Opus 5.5 and Sonnet
5
+ * 5.5 request. It enables effort changes carried by an empty `role: "system"`
6
+ * message on those two models.
7
+ */
8
+ export declare const PER_TURN_CONTROL_BETA = "per-turn-control-2026-07-01";
2
9
  export type AdaptiveEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
3
10
  export type MidConversationEffortTransition = {
4
11
  /** Number of assistant messages preceding the user boundary for this effort. */
@@ -6,7 +13,35 @@ export type MidConversationEffortTransition = {
6
13
  effort: AdaptiveEffort;
7
14
  };
8
15
  export declare function normalizeAdaptiveEffort(value: unknown): AdaptiveEffort | undefined;
16
+ /**
17
+ * Whether an OAuth request for this model carries the Fable 5.1 per-message
18
+ * effort beta (`MID_CONVERSATION_OUTPUT_CONFIG_BETA`). Opus 5.5 and Sonnet
19
+ * 5.5 use `PER_TURN_CONTROL_BETA` instead.
20
+ */
9
21
  export declare function usesMidConversationOutputConfig(body: Record<string, unknown>): boolean;
22
+ /**
23
+ * Opus 5.5 and Sonnet 5.5, including dated and `[1m]` context-window ids.
24
+ * Their OAuth requests always carry `PER_TURN_CONTROL_BETA`, as Claude Code's
25
+ * do. Anthropic also documents per-message effort for Mythos 5.1, Opus 5 and
26
+ * Haiku 5.5, but without a Claude Code capture to match, those models keep
27
+ * sending requests without the beta or effort markers.
28
+ */
29
+ export declare function usesPerTurnControl(model: unknown): boolean;
30
+ /**
31
+ * Whether a request may move effort changes into empty system messages.
32
+ *
33
+ * Fable 5.1 is always eligible, whatever its thinking field says. Opus 5.5
34
+ * and Sonnet 5.5 qualify only with adaptive thinking: Anthropic rejects a
35
+ * differing per-message effort with HTTP 400 on Sonnet 5.5 `between_tools`,
36
+ * and asks callers to use adaptive thinking to vary effort.
37
+ */
38
+ export declare function supportsPerMessageEffort(body: Record<string, unknown>): boolean;
39
+ /**
40
+ * The effort Anthropic applies when a request sets no `output_config.effort`:
41
+ * `medium` on Opus 5.5 and Haiku 5.5, `high` on the other models.
42
+ * A history entry without a recognized effort level uses this value.
43
+ */
44
+ export declare function defaultAdaptiveEffort(model: unknown): AdaptiveEffort;
10
45
  export declare function applyMidConversationOutputConfig(body: Record<string, unknown>, transitions: readonly MidConversationEffortTransition[]): {
11
46
  applied: boolean;
12
47
  inserted: number;
@@ -5,12 +5,13 @@ import { type NativeAccountMetadataPatch, type NativeAccountSnapshot, type Nativ
5
5
  import { type NativeCustodyReceipt } from './native-custody.ts';
6
6
  import { type NativeLocalCredentialServiceOptions } from './native-local-credential-service.ts';
7
7
  import type { NativeLocalExternalPolicy } from './native-local-runtime-readers.ts';
8
+ import { type NativeQuotaObservations } from './native-quota-observations.ts';
8
9
  import type { NativeKnownCredentialSubject, NativeRefreshResult, NativeRefreshSubject } from './native-refresh-coordinator.ts';
9
10
  import { type NativeDisplayProfile, type NativeVaultRuntime, type NativeVaultRuntimeOptions } from './native-vault-runtime.ts';
10
11
  import { type NativeLocalPoolBinding } from './pool-binding.ts';
11
- import type { NativePoolPaths } from './pool-paths.ts';
12
+ import { type NativePoolPaths } from './pool-paths.ts';
12
13
  import type { QuotaRequestDispatch } from './quota-manager.ts';
13
- import type { RelayConfig } from './relay.ts';
14
+ import { type RelayConfig } from './relay.ts';
14
15
  export type { NativeAccountMetadataPatch, NativeAccountSnapshot, NativeAccountView, } from './native-account-view.ts';
15
16
  export interface NativeAccountRuntimeOptions {
16
17
  paths: NativePoolPaths;
@@ -45,6 +46,8 @@ export type NativeRelayUpdate = Partial<Omit<RelayConfig, 'token'>> & {
45
46
  };
46
47
  export interface NativeAccountRuntime {
47
48
  readonly vault: NativeVaultRuntime;
49
+ readonly quotaObservations: NativeQuotaObservations;
50
+ drainQuotaPublications(): Promise<void>;
48
51
  /** Fresh private relay authorization for transport only; never include it in a status snapshot. */
49
52
  getRelayConfig(): Promise<RelayConfig | null>;
50
53
  updateRelay(patch: NativeRelayUpdate): Promise<void>;
@@ -108,6 +111,7 @@ export interface NativeAccountRuntime {
108
111
  /** Like fetchProfile, but returns before the profile is saved; see NativeDisplayProfile. */
109
112
  fetchProfileForDisplay(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<NativeDisplayProfile>;
110
113
  close(): void;
114
+ getSettingsPath(): Promise<string>;
111
115
  }
112
116
  /** Host instances own leases, while stores and the vault connection live until the last release. */
113
117
  export declare function acquireNativeAccountRuntime(options: NativeAccountRuntimeOptions): NativeAccountRuntime;
@@ -10,6 +10,7 @@ export interface NativeAccountView {
10
10
  id: string;
11
11
  type: 'oauth' | 'api';
12
12
  source: 'local' | 'vault';
13
+ /** User setting, not serving eligibility; use nativeAccountCanServe for runtime work. */
13
14
  enabled: boolean;
14
15
  label?: string;
15
16
  addedAt?: number;
@@ -30,14 +31,29 @@ export interface NativeAccountView {
30
31
  baseURL?: string;
31
32
  authHeader?: 'authorization-bearer' | 'x-api-key';
32
33
  }
34
+ /**
35
+ * Serving requires the user's permission and an active vault credential.
36
+ * Native views name their source; roster rows use credentialId and token-free
37
+ * policy rows use claustrumScopedCredentialId. Local policy rows default to on
38
+ * when the optional enabled setting is absent.
39
+ */
40
+ export declare function nativeAccountCanServe(account: {
41
+ enabled?: boolean;
42
+ source?: NativeAccountView['source'];
43
+ state?: string;
44
+ credentialId?: string;
45
+ claustrumScopedCredentialId?: string;
46
+ claustrumScopedState?: string;
47
+ } | null | undefined): boolean;
33
48
  /**
34
49
  * One-line status text for an account's state, shared by host status
35
50
  * displays. A local account in 'unsupported-access' holds a saved access value
36
51
  * 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.
52
+ * refreshed, so the text names the remedy. Vault states describe why an
53
+ * account cannot serve without changing the user's enabled setting.
54
+ * Returns '' when there is no state.
39
55
  */
40
- export declare function formatNativeAccountState(view: Pick<NativeAccountView, 'state'>): string;
56
+ export declare function formatNativeAccountState(view: Pick<NativeAccountView, 'state'> & Partial<Pick<NativeAccountView, 'source' | 'enabled'>>): string;
41
57
  export interface NativeAccountSnapshot {
42
58
  mode: 'local' | 'claustrum';
43
59
  settings: Record<string, unknown>;
@@ -3,7 +3,7 @@ import { type NativeHostAuthWriteHooks } from './native-host-auth-write.ts';
3
3
  import { type NativeMigrationJournal } from './pool-authority.ts';
4
4
  import type { NativePoolPaths } from './pool-paths.ts';
5
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';
6
+ export type NativeCustodyActivationErrorCode = 'migration-required' | 'invalid-journal' | '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
7
  export declare class NativeCustodyActivationError extends Error {
8
8
  readonly code: NativeCustodyActivationErrorCode;
9
9
  constructor(code: NativeCustodyActivationErrorCode);
@@ -212,7 +212,7 @@ export type NativeMenuExecutionResult = {
212
212
  */
213
213
  readonly status: 'failed';
214
214
  readonly action: NativeMenuDispatchActionId | 'vault-disconnect';
215
- readonly code: 'execution-failed' | 'invalid-outcome';
215
+ readonly code: 'execution-failed' | 'invalid-outcome' | 'disconnect-unsafe-file' | 'disconnect-wrong-consumer' | 'disconnect-pi-recovery' | 'disconnect-conflict' | 'disconnect-busy' | 'disconnect-io';
216
216
  } | {
217
217
  /** The host's disconnect capability ran and reported this result. */
218
218
  readonly status: 'disconnect';
@@ -1,14 +1,15 @@
1
1
  import { type PoolRow } from "./internal-types/store/index.js";
2
+ import type { NativeAccountSnapshot } from './native-account-view.ts';
2
3
  import type { NativeCustodyInventory } from './native-custody.ts';
3
4
  import { type NativeHostAuthWriteHooks } from './native-host-auth-write.ts';
4
5
  import { type NativeRosterSeedInput, type NativeVaultRosterSeed } from './native-roster-seed.ts';
5
6
  import { type NativeRuntimeState } from './native-runtime.ts';
6
- import { type NativeMigrationJournal } from './pool-authority.ts';
7
+ import { type NativeEmptyInitJournal, type NativeLegacyMigrationJournal } from './pool-authority.ts';
7
8
  import { type NativePoolPaths } from './pool-paths.ts';
8
9
  import { createNativePoolStore } from './pool-store.ts';
9
10
  export declare class NativeMigrationError extends Error {
10
- readonly code: 'invalid-source' | 'unsafe-source' | 'consent-required' | 'primary-unverified' | 'migration-busy' | 'ownership-lost' | 'retirement-refused';
11
- constructor(code: 'invalid-source' | 'unsafe-source' | 'consent-required' | 'primary-unverified' | 'migration-busy' | 'ownership-lost' | 'retirement-refused');
11
+ readonly code: 'invalid-source' | 'unsafe-source' | 'consent-required' | 'primary-unverified' | 'migration-busy' | 'ownership-lost' | 'pool-populated' | 'host-login-present' | 'settings-changed' | 'retirement-refused';
12
+ constructor(code: 'invalid-source' | 'unsafe-source' | 'consent-required' | 'primary-unverified' | 'migration-busy' | 'ownership-lost' | 'pool-populated' | 'host-login-present' | 'settings-changed' | 'retirement-refused');
12
13
  }
13
14
  export interface NativeMigrationCustody {
14
15
  /** Use the host’s approved Claustrum token and account-list permission to discover accounts; never open the vault’s credential files. */
@@ -54,6 +55,26 @@ export interface NativeMigrationHooks {
54
55
  hostWrite?: NativeHostAuthWriteHooks;
55
56
  store?: Pick<Parameters<typeof createNativePoolStore>[0], 'onStep' | 'onLockStep'>;
56
57
  }
58
+ /** Session pins and preferences do not establish account ownership. */
59
+ export declare function nativePoolHoldsAccountData({ paths, }: {
60
+ paths: NativePoolPaths;
61
+ }): Promise<boolean>;
62
+ /** Only enabled local OAuth rows can authorize local OAuth serving. */
63
+ export declare function snapshotHasServableLocalOAuth(snapshot: Pick<NativeAccountSnapshot, 'accounts'>): boolean;
64
+ export interface NativeEmptyInitOptions {
65
+ paths: NativePoolPaths;
66
+ routingDestinationPath: string;
67
+ processFence: () => Promise<void>;
68
+ env: NodeJS.ProcessEnv;
69
+ }
70
+ export interface NativeEmptyInitHooks extends Pick<NativeMigrationHooks, 'onStep'> {
71
+ lockOptions?: {
72
+ ttlMs: number;
73
+ timeoutMs: number;
74
+ };
75
+ }
76
+ /** Establish local authority for a new OpenCode pool without reading legacy credentials. */
77
+ export declare function publishNativeEmptyInit(input: NativeEmptyInitOptions, hooks?: NativeEmptyInitHooks): Promise<NativeEmptyInitJournal>;
57
78
  /** Preflight is read-only so setup can validate all selected hosts before any begin. */
58
79
  export declare function prepareNativeMigration(input: NativeMigrationOptions): Promise<NativeMigrationPreflight>;
59
80
  export declare function releaseNativeMigrationPreflight(token: NativeMigrationPreflight): void;
@@ -63,4 +84,4 @@ export declare function releaseNativeMigrationPreflight(token: NativeMigrationPr
63
84
  */
64
85
  export declare function importedRuntimeProjection(paths: NativePoolPaths, store: ReturnType<typeof createNativePoolStore>, rows: PoolRow[]): Promise<unknown>;
65
86
  /** Offline, crash-forward transaction. Native serving never calls this controller. */
66
- export declare function runNativeMigration(input: NativeMigrationOptions, hooks?: NativeMigrationHooks): Promise<NativeMigrationJournal>;
87
+ export declare function runNativeMigration(input: NativeMigrationOptions, hooks?: NativeMigrationHooks): Promise<NativeLegacyMigrationJournal>;
@@ -0,0 +1,26 @@
1
+ import { type AccountStorage, type OAuthQuotaSnapshot } from './accounts.ts';
2
+ import type { NativeLocalPoolBinding } from './pool-binding.ts';
3
+ import type { QuotaEntry } from './quota-manager.ts';
4
+ export type NativeQuotaObservation = {
5
+ lineage: string;
6
+ accountUuid: string;
7
+ entry: QuotaEntry;
8
+ generalExhausted: boolean;
9
+ quotaErrorClearedAt?: number;
10
+ };
11
+ export declare function nativePollQuotaGenerallyExhausted(quota: OAuthQuotaSnapshot): boolean;
12
+ export declare function nativeLocalQuotaLineage(binding: NativeLocalPoolBinding & {
13
+ readonly identity: string;
14
+ }): string;
15
+ export declare function nativeLocalQuotaLineage(binding: NativeLocalPoolBinding | undefined): string | undefined;
16
+ /** Shared by header receipt, poll completion, routing and display; contains no credentials. */
17
+ export declare class NativeQuotaObservations extends Map<string, NativeQuotaObservation> {
18
+ private readonly publications;
19
+ set(accountId: string, observation: NativeQuotaObservation): this;
20
+ quota(lineage: string | undefined, accountUuid: string | undefined, committed: OAuthQuotaSnapshot | undefined, storage: AccountStorage, now?: number): {
21
+ quota: OAuthQuotaSnapshot;
22
+ clearAt?: number;
23
+ } | undefined;
24
+ publish(accountId: string, observation: NativeQuotaObservation, write: () => Promise<boolean>): Promise<void>;
25
+ drain(): Promise<void>;
26
+ }
@@ -31,8 +31,7 @@ export declare function isNativeTransientAccountError(value: unknown): value is
31
31
  * budget. Each wait between attempts ends early when any of `signals`
32
32
  * aborts; `check` is then called after the leases are released and is
33
33
  * expected to throw the caller's cancellation error. `check` runs before
34
- * every attempt too, so a cancelled caller never takes a lock. `now` must be
35
- * the clock the pool's writers stamp their lock expiry with, or a live
36
- * writer's lock could be judged expired and taken over.
34
+ * every attempt too, so a cancelled caller never takes a lock. All pool
35
+ * leases use wall time, independently of logical observation timestamps.
37
36
  */
38
- export declare function joinNativePoolWrite(paths: NativePoolStorePaths, signals: readonly AbortSignal[], check: () => void, now?: () => number): Promise<'joined' | 'deadline'>;
37
+ export declare function joinNativePoolWrite(paths: NativePoolStorePaths, signals: readonly AbortSignal[], check: () => void): Promise<'joined' | 'deadline'>;
@@ -21,6 +21,8 @@ export interface NativeUiOptions {
21
21
  readonly readMode: () => Promise<NativeMenuCustodyMode>;
22
22
  /** Token-free account names, credential IDs and states used to show which vault account needs re-login and its replacement command. */
23
23
  readonly readAccounts?: () => Promise<import('./native-account-view.ts').NativeAccountSnapshot>;
24
+ /** Re-read the separate host-login notice on each local Accounts render. */
25
+ readonly readSeparateHostLoginNotice?: () => Promise<boolean>;
24
26
  /**
25
27
  * Disconnects this host from the vault; while enrolled, this is the host's
26
28
  * only enrollment action. Before ending the enrollment, the callback
@@ -4,6 +4,11 @@
4
4
  * The error classes are not public runtime exports, so match name and code.
5
5
  */
6
6
  export declare function usagePublicationRefusalIsFatal(error: unknown): boolean;
7
+ /** Return only allowlisted classes and codes, never the exception text. */
8
+ export declare function classifySafeErrorForLog(error: unknown): {
9
+ name: string;
10
+ code: string;
11
+ };
7
12
  /** Own advisory writes for one host instance and join them before runtime close. */
8
13
  export declare function createNativeUsagePublisher(channel: string): {
9
14
  observe: (write: Promise<unknown>) => Promise<void>;
@@ -2,6 +2,7 @@ import { type ClaustrumClientOptions } from '@cortexkit/claustrum-client';
2
2
  import { type OAuthAccountProfile, type OAuthQuotaSnapshot, type PrimeUsageDelta } from './accounts.ts';
3
3
  import { type NativeAccountMetadataPatch } from './native-account-view.ts';
4
4
  import { type NativeCustodyClient, type NativeCustodyInventory, type NativeCustodyReceipt, type NativeCustodyReporterSource, type NativeCustodyRetry } from './native-custody.ts';
5
+ import { NativeQuotaObservations } from './native-quota-observations.ts';
5
6
  import { type NativeRosterSeedInput, type NativeVaultRosterDocument, type NativeVaultRosterSeed } from './native-roster-seed.ts';
6
7
  import { type NativeRuntimeState } from './native-runtime.ts';
7
8
  import type { NativeVaultPaths } from './native-vault-paths.ts';
@@ -53,6 +54,9 @@ export interface NativeDisplayProfile {
53
54
  /** Build a NativeDisplayProfile from a validated profile and its publication. */
54
55
  export declare function nativeDisplayProfile(profile: OAuthAccountProfile, publish: () => Promise<boolean>, isCurrent: () => Promise<boolean>): NativeDisplayProfile;
55
56
  export interface NativeVaultRuntime {
57
+ readonly quotaObservations: NativeQuotaObservations;
58
+ drainQuotaPublications(): Promise<void>;
59
+ quotaLineage(routeId: string, credentialId: string | undefined, accountIdentity: string | undefined): string | undefined;
56
60
  /** Subscribe to one discovery loop; notifications contain no credential material. */
57
61
  watch(options: NativeVaultWatchOptions): NativeVaultWatch;
58
62
  initializeSettings(): Promise<void>;
@@ -1 +1,2 @@
1
+ export declare function transientNetworkErrorCode(error: unknown): string | undefined;
1
2
  export declare function isTransientNetworkError(error: unknown): boolean;
@@ -23,6 +23,7 @@ export interface NativeMigrationInput {
23
23
  * keeps native serving blocked until the separate vault activation commits.
24
24
  */
25
25
  activation?: 'requested';
26
+ nativeSettingsDigest?: string;
26
27
  }
27
28
  export interface NativeMigrationExpectations {
28
29
  expectedHostAuth: string;
@@ -97,8 +98,7 @@ export interface NativeCustodyActivationPlan {
97
98
  export type NativeCustodyActivation = {
98
99
  kind: 'requested';
99
100
  } | NativeCustodyActivationPlan;
100
- export interface NativeMigrationJournal {
101
- version: 4;
101
+ interface NativeMigrationRecord {
102
102
  storageId: string;
103
103
  host: 'opencode' | 'pi';
104
104
  phase: NativeMigrationPhase;
@@ -114,6 +114,22 @@ export interface NativeMigrationJournal {
114
114
  */
115
115
  activation: NativeCustodyActivation | null;
116
116
  }
117
+ export type NativeLegacyMigrationJournal = NativeMigrationRecord & ({
118
+ version: 4;
119
+ kind?: never;
120
+ } | {
121
+ version: 5;
122
+ kind: 'legacy-import';
123
+ nativeSettingsDigest: string;
124
+ });
125
+ export interface NativeEmptyInitJournal {
126
+ version: 5;
127
+ kind: 'empty-init';
128
+ storageId: string;
129
+ host: 'opencode';
130
+ phase: 'committed';
131
+ }
132
+ export type NativeMigrationJournal = NativeLegacyMigrationJournal | NativeEmptyInitJournal;
117
133
  export declare class NativeAuthorityError extends Error {
118
134
  readonly code: 'migration-required' | 'migration-incomplete' | 'invalid-journal' | 'journal-conflict';
119
135
  constructor(code: 'migration-required' | 'migration-incomplete' | 'invalid-journal' | 'journal-conflict');
@@ -137,23 +153,25 @@ interface JournalHooks {
137
153
  onWriteStep?: (step: 'before-write' | 'after-write', journal: NativeMigrationJournal) => Promise<void>;
138
154
  }
139
155
  /** Migration resume retains the original digests and resolved paths so a retry cannot adopt changed inputs or redirect writes. */
140
- export declare function beginNativeMigration(paths: NativePoolPaths, input: NativeMigrationInput, hooks?: JournalHooks): Promise<NativeMigrationJournal>;
156
+ export declare function beginNativeMigration(paths: NativePoolPaths, input: NativeMigrationInput, hooks?: JournalHooks): Promise<NativeLegacyMigrationJournal>;
141
157
  /** Save the expected host-auth entry and routing digests together before changing files, so recovery can recognize completed writes. */
142
- export declare function recordNativeMigrationExpectations(paths: NativePoolPaths, expectations: NativeMigrationExpectations, hooks?: JournalHooks): Promise<NativeMigrationJournal>;
158
+ export declare function recordNativeMigrationExpectations(paths: NativePoolPaths, expectations: NativeMigrationExpectations, hooks?: JournalHooks): Promise<NativeLegacyMigrationJournal>;
143
159
  /**
144
160
  * Advance one phase at a time. A retry of the same transition returns the journal.
145
161
  * Before recording activation, the caller must compare the host's Anthropic auth
146
162
  * entry and routing file with the saved expected values. This journal records the
147
163
  * migration stage; it does not read or verify those files.
148
164
  */
149
- export declare function advanceNativeMigration(paths: NativePoolPaths, expected: NativeMigrationPhase, next: NativeMigrationPhase, hooks?: JournalHooks): Promise<NativeMigrationJournal>;
165
+ export declare function advanceNativeMigration(paths: NativePoolPaths, expected: NativeMigrationPhase, next: NativeMigrationPhase, hooks?: JournalHooks): Promise<NativeLegacyMigrationJournal>;
150
166
  /**
151
167
  * Record the prepared switch to vault custody on a retired migration. From
152
168
  * this write until the activation commits, the pool authorizes no serving.
153
169
  * Retrying with the identical plan returns the journal; any other plan is a
154
170
  * conflict, so a resumed setup can never replace what it recorded.
155
171
  */
156
- export declare function recordNativeCustodyActivation(paths: NativePoolPaths, plan: NativeCustodyActivationPlan, hooks?: JournalHooks): Promise<NativeMigrationJournal>;
172
+ export declare function recordNativeCustodyActivation(paths: NativePoolPaths, plan: NativeCustodyActivationPlan, hooks?: JournalHooks): Promise<NativeLegacyMigrationJournal>;
157
173
  /** Advance a recorded activation one phase; never backwards or across a phase. */
158
- export declare function advanceNativeCustodyActivation(paths: NativePoolPaths, expected: NativeCustodyActivationPhase, next: NativeCustodyActivationPhase, hooks?: JournalHooks): Promise<NativeMigrationJournal>;
174
+ export declare function advanceNativeCustodyActivation(paths: NativePoolPaths, expected: NativeCustodyActivationPhase, next: NativeCustodyActivationPhase, hooks?: JournalHooks): Promise<NativeLegacyMigrationJournal>;
175
+ /** Publish local authority without inventing migration inputs or creating a pool. */
176
+ export declare function beginNativeEmptyInit(paths: NativePoolPaths, hooks?: JournalHooks): Promise<NativeEmptyInitJournal>;
159
177
  export {};
@@ -8,6 +8,8 @@ export interface NativePoolPaths {
8
8
  roster: string;
9
9
  storageId: string;
10
10
  }
11
+ /** Local hosts share the native pool's routing file unless explicitly overridden. */
12
+ export declare function resolveLocalRoutingDestination(host: 'opencode' | 'pi', paths: NativePoolPaths, env: NodeJS.ProcessEnv): string;
11
13
  /**
12
14
  * Resolve existing parent aliases and nonexistent leaves without creating files.
13
15
  * This can follow a leaf symlink, so it does not establish configured-leaf safety.