@cortexkit/anthropic-auth-core 2.0.1 → 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 (58) 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 +27470 -25081
  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/codec.d.ts +2 -0
  20. package/dist/internal-types/quota/format.d.ts +26 -0
  21. package/dist/internal-types/quota/index.d.ts +4 -4
  22. package/dist/internal-types/quota/map.d.ts +11 -0
  23. package/dist/internal-types/quota/merge.d.ts +3 -1
  24. package/dist/internal-types/quota/projection.d.ts +2 -1
  25. package/dist/internal-types/routing/admission.d.ts +93 -0
  26. package/dist/internal-types/routing/index.d.ts +8 -0
  27. package/dist/internal-types/routing/ordered.d.ts +47 -0
  28. package/dist/internal-types/routing/pins.d.ts +22 -0
  29. package/dist/internal-types/routing/sticky.d.ts +158 -0
  30. package/dist/internal-types/setup/command-error.d.ts +17 -0
  31. package/dist/internal-types/setup/command.d.ts +3 -0
  32. package/dist/internal-types/setup/detect.d.ts +6 -0
  33. package/dist/internal-types/setup/index.d.ts +6 -0
  34. package/dist/internal-types/setup/process-fence.d.ts +43 -0
  35. package/dist/internal-types/setup/register.d.ts +11 -0
  36. package/dist/internal-types/setup/types.d.ts +138 -0
  37. package/dist/internal-types/store/pool.d.ts +1 -1
  38. package/dist/internal-types/store/refresh-lock.d.ts +0 -1
  39. package/dist/internal-types/store/schema.d.ts +2 -0
  40. package/dist/logging.d.ts +2 -0
  41. package/dist/mid-conversation-output-config.d.ts +35 -0
  42. package/dist/native-account-runtime.d.ts +6 -2
  43. package/dist/native-account-view.d.ts +22 -4
  44. package/dist/native-custody-activation.d.ts +1 -1
  45. package/dist/native-menu-executor.d.ts +1 -1
  46. package/dist/native-migration.d.ts +25 -4
  47. package/dist/native-quota-observations.d.ts +26 -0
  48. package/dist/native-transient-account.d.ts +3 -4
  49. package/dist/native-ui.d.ts +2 -0
  50. package/dist/native-usage-publication.d.ts +5 -0
  51. package/dist/native-vault-runtime.d.ts +4 -0
  52. package/dist/network-errors.d.ts +1 -0
  53. package/dist/pool-authority.d.ts +26 -8
  54. package/dist/pool-paths.d.ts +2 -0
  55. package/dist/quotas.d.ts +15 -2
  56. package/dist/relay.d.ts +20 -0
  57. package/dist/sticky-routing.d.ts +3 -0
  58. package/package.json +3 -2
@@ -0,0 +1,158 @@
1
+ import { type ProjectedQuota } from '../quota/projection.js';
2
+ import { type AdmissionInput, type AdmissionRefusal, type AdmissionResult, type RoutingRow, type WindowRef } from './admission.js';
3
+ import { type StickyPin } from './pins.js';
4
+ export declare const QUOTA_STALENESS_MS: number;
5
+ export declare const MIN_RESET_HOURS: number;
6
+ export declare const MIN_WEIGHT = 0.000001;
7
+ /** The projection's time, else the caller's cache-entry time. */
8
+ export declare function snapshotCheckedAt(quota: ProjectedQuota | null | undefined, entryCheckedAt?: number): number | undefined;
9
+ export type StickyBreakDecision = {
10
+ action: 'retain';
11
+ reason: 'unknown' | 'stale' | 'healthy' | 'transient';
12
+ } | {
13
+ action: 'migrate';
14
+ reason: 'exhausted' | 'permanent' | 'killswitch';
15
+ /** The exhausted limit, named by its (scope, label), not its position. */
16
+ window?: WindowRef;
17
+ resetsAt?: string;
18
+ };
19
+ /**
20
+ * How the adapter reads a failed response's HTTP status for the break
21
+ * decision. `permanent` moves the session off its row before any quota is
22
+ * consulted; `transient` and `healthy` keep it unless the quota says the row
23
+ * is spent. A missing status means the request failed without a response.
24
+ */
25
+ export type StickyStatusClass = 'permanent' | 'transient' | 'healthy';
26
+ export type StickyStatusClassifier = (status: number | undefined) => StickyStatusClass;
27
+ /**
28
+ * The status rule used when the adapter supplies none, carried from
29
+ * openai-auth: 401 and 403 are permanent; no response, 0, a non-finite
30
+ * status, 429 and 5xx are transient; anything else leaves the row healthy.
31
+ * A provider whose 403 can mean an organisation or model policy rather than
32
+ * a dead account supplies its own classifier and can fall back to this one
33
+ * for the statuses it does not single out.
34
+ */
35
+ export declare function defaultStickyStatusClass(status: number | undefined): StickyStatusClass;
36
+ /** Classifies whether a pinned session should leave its row after a failure. */
37
+ export declare function decideStickyBreak(input: {
38
+ quota: ProjectedQuota | null | undefined;
39
+ quotaCheckedAt?: number;
40
+ status?: number;
41
+ now: number;
42
+ killswitchPasses?: boolean;
43
+ /** Defaults to `defaultStickyStatusClass`. */
44
+ classifyStatus?: StickyStatusClassifier;
45
+ }): StickyBreakDecision;
46
+ export declare function sustainableWindowWeight(window: {
47
+ remainingPercent: number;
48
+ resetsAt?: string;
49
+ }, reservePercent: number, now: number): number;
50
+ export interface StickySelectionCandidate {
51
+ accountId: string;
52
+ quota: ProjectedQuota | null | undefined;
53
+ quotaCheckedAt?: number;
54
+ /** Reserve percent per window label; a missing label reserves nothing. */
55
+ reservePercent: Readonly<Record<string, number>>;
56
+ configuredOrder: number;
57
+ resetCreditsApplicable?: number;
58
+ /** `false` excludes the candidate from weighted and fallback placement. */
59
+ killswitchPasses?: boolean;
60
+ }
61
+ export interface StickySelectionInput {
62
+ candidates: readonly StickySelectionCandidate[];
63
+ pendingBytes: ReadonlyMap<string, number>;
64
+ requestBytes: number;
65
+ now: number;
66
+ onEmptyWeightedSet?: () => void;
67
+ }
68
+ export interface StickySelection {
69
+ accountId: string;
70
+ quotaCheckedAt?: number;
71
+ source: 'weighted' | 'mode-fallback';
72
+ }
73
+ /**
74
+ * Places a session: the lowest projected pressure among candidates with a
75
+ * fresh positive weight, else (`mode-fallback`) the first candidate in
76
+ * configured order, preferring one with an applicable reset credit.
77
+ */
78
+ export declare function selectStickyCandidate(input: StickySelectionInput): StickySelection | undefined;
79
+ /** Reserve percent per window label; a missing label reserves nothing. */
80
+ export type ReservePercent = Readonly<Record<string, number>>;
81
+ /**
82
+ * Reserve percentages per row: a map keyed by row id, or a function of the
83
+ * row. A row the map lacks, or for which the function returns undefined,
84
+ * takes the shared `reservePercent`.
85
+ */
86
+ export type RowReservePercent = ReadonlyMap<string, ReservePercent> | ((row: RoutingRow) => ReservePercent | undefined);
87
+ /**
88
+ * What a valid pin does when its row is not dispatched.
89
+ *
90
+ * `keep`: the pin is retained whatever kept its row from this request.
91
+ *
92
+ * `move-on-confirmed-exhaustion`: the pin moves to the row this request is
93
+ * dispatched to when its own row was refused as confirmed exhausted (a spent
94
+ * window with a future reset, or a spent credit budget) or killed by the
95
+ * killswitch. A refusal for unknown quota (no reading yet, a missing window,
96
+ * an exhausted reading without a usable reset) and an exclusion (rate-limit
97
+ * mark, refresh backoff) keep the pin while this request is served elsewhere.
98
+ * With no admissible row the pin is retained either way.
99
+ */
100
+ export type RefusedPinPolicy = 'keep' | 'move-on-confirmed-exhaustion';
101
+ export interface StickyRouteInput extends AdmissionInput {
102
+ requestBytes: number;
103
+ /** Bytes already committed per row, for example from other sessions' pins. */
104
+ pendingBytes?: ReadonlyMap<string, number>;
105
+ /** Killswitch verdict per row; a missing row passes. */
106
+ killswitch?: ReadonlyMap<string, boolean>;
107
+ /** Reserve percent per window label, for every row without its own. */
108
+ reservePercent?: ReservePercent;
109
+ /** Per-row reserves, which replace `reservePercent` for the rows they cover. */
110
+ rowReservePercent?: RowReservePercent;
111
+ /** Defaults to `keep`. */
112
+ refusedPinPolicy?: RefusedPinPolicy;
113
+ resetCreditsApplicable?: ReadonlyMap<string, number>;
114
+ /** The session's current pin, if it has one. */
115
+ pin?: StickyPin;
116
+ /** Each row's recorded wire identity; missing means unknown. */
117
+ identities?: ReadonlyMap<string, string | undefined>;
118
+ onEmptyWeightedSet?: () => void;
119
+ }
120
+ /**
121
+ * What the caller does with the session's pin: keep it, replace it with
122
+ * `pin`, or drop it. Under the default `keep` policy a valid pin is always
123
+ * kept, even when this request was routed elsewhere because its row was
124
+ * refused, excluded or killed; `refusedPinPolicy` can move it instead.
125
+ */
126
+ export type PinAction = {
127
+ action: 'retain';
128
+ } | {
129
+ action: 'assign';
130
+ pin: StickyPin;
131
+ } | {
132
+ action: 'clear';
133
+ } | {
134
+ action: 'none';
135
+ };
136
+ export type StickyRoute = {
137
+ outcome: 'dispatch';
138
+ accountId: string;
139
+ source: 'pin' | 'weighted' | 'mode-fallback';
140
+ quotaCheckedAt?: number;
141
+ pin: PinAction;
142
+ /** Rows that selection chose and admission then refused, in selection order. */
143
+ refusedSelections: AdmissionRefusal[];
144
+ admission: AdmissionResult;
145
+ } | {
146
+ outcome: 'no-admissible-account';
147
+ pin: PinAction;
148
+ refusedSelections: AdmissionRefusal[];
149
+ admission: AdmissionResult;
150
+ };
151
+ /**
152
+ * Routes one request in `sticky-balanced` mode. A valid pin whose row is
153
+ * admitted, not excluded and not killed is dispatched as is. Otherwise
154
+ * selection runs over the non-excluded rows; each selected row admission
155
+ * refused is removed and selection re-runs, so the loop ends either on an
156
+ * admitted row or with no admissible account.
157
+ */
158
+ export declare function routeSticky(input: StickyRouteInput): StickyRoute;
@@ -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;
@@ -49,6 +49,8 @@ export type StoredCredential = (OAuthCredential & {
49
49
  /** Quota codec supplied by `/quota`: the store never interprets the map itself. */
50
50
  export interface QuotaCodec {
51
51
  validate(value: unknown): boolean;
52
+ /** Normalize persisted quota before validation, when the codec supports it. */
53
+ decode?(value: unknown): unknown;
52
54
  merge(stored: unknown | undefined, observation: unknown): unknown;
53
55
  }
54
56
  /**
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,20 +31,37 @@ 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>;
44
60
  accounts: NativeAccountView[];
45
- /** Vault session-to-account assignments use this separate file. Local mode keeps the assignment file at the destination recorded by migration. */
61
+ /** Vault storage, or the local destination recorded by the authorized migration journal. */
46
62
  routingPath?: string;
63
+ /** Distinct pre-migration routing file that OpenCode local serving may have recreated. */
64
+ routingRecoveryPath?: string;
47
65
  routingSeed?: NativeVaultRoutingSeed;
48
66
  /** AccountStorage-shaped input for pure policy predicates, never a credential or persistence authority. */
49
67
  policyStorage: AccountStorage;
@@ -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>;