@cortexkit/anthropic-auth-core 2.0.2 → 2.1.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 (73) 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/cachekeep.d.ts +2 -0
  5. package/dist/cch.d.ts +19 -0
  6. package/dist/claude-code.d.ts +8 -2
  7. package/dist/claustrum-enrollment.d.ts +5 -1
  8. package/dist/constants.d.ts +15 -3
  9. package/dist/dump.d.ts +4 -0
  10. package/dist/fast.d.ts +2 -0
  11. package/dist/index.d.ts +15 -8
  12. package/dist/index.js +29647 -25296
  13. package/dist/insula-quota.d.ts +25 -0
  14. package/dist/internal-types/auth-menu/terminal.d.ts +43 -0
  15. package/dist/internal-types/claustrum/availability.d.ts +89 -0
  16. package/dist/internal-types/claustrum/consumer.d.ts +172 -0
  17. package/dist/internal-types/claustrum/custody.d.ts +299 -0
  18. package/dist/internal-types/claustrum/enrollment.d.ts +164 -0
  19. package/dist/internal-types/claustrum/errors.d.ts +17 -0
  20. package/dist/internal-types/claustrum/host-slot.d.ts +39 -0
  21. package/dist/internal-types/claustrum/index.d.ts +21 -0
  22. package/dist/internal-types/claustrum/insula.d.ts +117 -0
  23. package/dist/internal-types/claustrum/interlock.d.ts +27 -0
  24. package/dist/internal-types/claustrum/roster.d.ts +221 -0
  25. package/dist/internal-types/claustrum/watch.d.ts +141 -0
  26. package/dist/internal-types/fs/refresh-file-lock.d.ts +8 -2
  27. package/dist/internal-types/quota/format.d.ts +43 -3
  28. package/dist/internal-types/quota/index.d.ts +3 -3
  29. package/dist/internal-types/quota/projection.d.ts +16 -0
  30. package/dist/internal-types/routing/admission.d.ts +93 -0
  31. package/dist/internal-types/routing/index.d.ts +8 -0
  32. package/dist/internal-types/routing/ordered.d.ts +47 -0
  33. package/dist/internal-types/routing/pins.d.ts +22 -0
  34. package/dist/internal-types/routing/sticky.d.ts +158 -0
  35. package/dist/internal-types/setup/command-error.d.ts +32 -0
  36. package/dist/internal-types/setup/command.d.ts +3 -0
  37. package/dist/internal-types/setup/detect.d.ts +6 -0
  38. package/dist/internal-types/setup/index.d.ts +6 -0
  39. package/dist/internal-types/setup/process-fence.d.ts +43 -0
  40. package/dist/internal-types/setup/register.d.ts +11 -0
  41. package/dist/internal-types/setup/types.d.ts +150 -0
  42. package/dist/internal-types/store/pool.d.ts +1 -1
  43. package/dist/internal-types/store/refresh-lock.d.ts +0 -1
  44. package/dist/logging.d.ts +2 -0
  45. package/dist/mid-conversation-output-config.d.ts +34 -2
  46. package/dist/migration-source.d.ts +2 -0
  47. package/dist/native-account-runtime.d.ts +9 -4
  48. package/dist/native-account-view.d.ts +19 -3
  49. package/dist/native-custody-activation.d.ts +1 -1
  50. package/dist/native-custody.d.ts +130 -0
  51. package/dist/native-enrollment-authority.d.ts +5 -1
  52. package/dist/native-host-auth-read.d.ts +2 -1
  53. package/dist/native-host-auth-write.d.ts +2 -0
  54. package/dist/native-menu-executor.d.ts +1 -1
  55. package/dist/native-migration.d.ts +25 -4
  56. package/dist/native-quota-observations.d.ts +26 -0
  57. package/dist/native-runtime.d.ts +5 -1
  58. package/dist/native-transient-account.d.ts +3 -4
  59. package/dist/native-ui.d.ts +2 -0
  60. package/dist/native-usage-publication.d.ts +5 -0
  61. package/dist/native-vault-invalidation.d.ts +9 -0
  62. package/dist/native-vault-runtime.d.ts +36 -3
  63. package/dist/network-errors.d.ts +1 -0
  64. package/dist/owner-only.d.ts +19 -0
  65. package/dist/pool-authority.d.ts +27 -8
  66. package/dist/pool-paths.d.ts +2 -0
  67. package/dist/provider-error.d.ts +34 -0
  68. package/dist/publication-rename.d.ts +11 -0
  69. package/dist/quota-manager.d.ts +21 -4
  70. package/dist/quotas.d.ts +31 -2
  71. package/dist/relay.d.ts +20 -0
  72. package/dist/request-gzip.d.ts +99 -0
  73. package/package.json +4 -4
@@ -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, setupEnrollment } 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, SetupEnrollmentOutcome, SetupEnvironment, SetupFileSystem, SetupHost, SetupHostEnrollment, 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,150 @@
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 a setup run recorded about one host's vault enrollment when it failed:
8
+ * `enrolled` once approval landed and the token was written, `not-enrolled`
9
+ * when the host was never asked or its enrollment was refused or gave up
10
+ * waiting, and `unknown` when setup failed while the enrollment was still in
11
+ * flight and the host's token file could not settle it.
12
+ */
13
+ export type SetupEnrollmentOutcome = 'enrolled' | 'not-enrolled' | 'unknown';
14
+ export interface SetupHostEnrollment {
15
+ host: SetupHost;
16
+ outcome: SetupEnrollmentOutcome;
17
+ }
18
+ /**
19
+ * What setup decided before calling a plugin callback. The OpenCode generation
20
+ * is the one being registered, after `--opencode` or the interactive choice, so
21
+ * a plugin can sign in the way that generation expects (OpenCode 2 does not
22
+ * read OpenCode 1's login file).
23
+ */
24
+ export interface SetupCallbackContext {
25
+ opencodeGeneration: OpenCodeGeneration;
26
+ mode: 'local' | 'claustrum';
27
+ /**
28
+ * Every host this run sets up, in order, so the first `beforeSignIn` can
29
+ * check conditions across all of them (for example that their storage paths
30
+ * do not overlap) before any host is changed.
31
+ */
32
+ hosts: readonly SetupHost[];
33
+ /**
34
+ * Pi's agent folder, resolved the way Pi itself does (`PI_CODING_AGENT_DIR`,
35
+ * with `~` expanded, else `~/.pi/agent`). Pi's own `auth.json` lives here;
36
+ * use it rather than a plugin path setting, which can point elsewhere.
37
+ */
38
+ piAgentDir: string;
39
+ }
40
+ /** Provider login, credential migration and vault activation stay in plugin callbacks. */
41
+ export interface SetupPlugin {
42
+ packages: {
43
+ opencode: string;
44
+ pi: string;
45
+ };
46
+ version: string;
47
+ displayName: string;
48
+ slashCommand: string;
49
+ vault: {
50
+ connectionFile: string;
51
+ hosts: Record<SetupHost, {
52
+ name: string;
53
+ paths: Parameters<typeof hostEnrollmentPaths>[0];
54
+ }>;
55
+ };
56
+ /**
57
+ * Runs for each host on a real run after the host, mode and generation are
58
+ * chosen and before the vault ceremony or `signInLocal`, while nothing has
59
+ * changed yet. Rejecting stops setup for that host, so a plugin can ask for
60
+ * consent or check preconditions before any credential or authority change.
61
+ */
62
+ beforeSignIn?(host: SetupHost, context: SetupCallbackContext): Promise<void>;
63
+ signInLocal(host: SetupHost, context: SetupCallbackContext): Promise<void>;
64
+ migrate(host: SetupHost, context: SetupCallbackContext): Promise<void>;
65
+ /** Reject mixed local/vault credentials and activate provider-specific vault access before registration. */
66
+ beforeRegister?(host: SetupHost, mode: 'local' | 'claustrum', context: SetupCallbackContext): Promise<void>;
67
+ }
68
+ export interface CommandResult {
69
+ exitCode: number;
70
+ stdout: string;
71
+ stderr: string;
72
+ spawnError?: boolean;
73
+ stderrTruncated?: boolean;
74
+ signal?: NodeJS.Signals | null;
75
+ timedOut?: boolean;
76
+ durationMs?: number;
77
+ }
78
+ export interface CommandRunner {
79
+ run(file: string, args: readonly string[], options?: {
80
+ env?: SetupEnvironment;
81
+ timeoutMs?: number;
82
+ windowsVerbatimArguments?: boolean;
83
+ }): Promise<CommandResult>;
84
+ }
85
+ export interface SetupFileSystem {
86
+ exists(path: string): boolean;
87
+ isDirectory(path: string): boolean;
88
+ isFile(path: string): boolean;
89
+ isExecutable(path: string): boolean;
90
+ readText(path: string): string;
91
+ realpath(path: string): string;
92
+ }
93
+ export interface ProcessFence {
94
+ listRunningHosts(env?: SetupEnvironment): Promise<Array<{
95
+ pid: number;
96
+ command: string;
97
+ }>>;
98
+ /**
99
+ * For a dry run, which must change nothing: the hosts found without starting
100
+ * any program that writes files. On Windows that skips the PowerShell query
101
+ * for Node and Bun command lines (PowerShell writes a startup cache into the
102
+ * user's profile), so Node or Bun processes are only counted. A fence without
103
+ * it is previewed with `listRunningHosts`.
104
+ */
105
+ previewRunningHosts?(env?: SetupEnvironment): Promise<{
106
+ hosts: Array<{
107
+ pid: number;
108
+ command: string;
109
+ }>;
110
+ uncheckedRuntimes: number;
111
+ }>;
112
+ }
113
+ /** Defaults use the process terminal and environment; overrides are test seams. */
114
+ export interface SetupIO {
115
+ terminal?: MenuTerminal;
116
+ env?: SetupEnvironment;
117
+ platform?: string;
118
+ home?: string;
119
+ cwd?: string;
120
+ fs?: SetupFileSystem;
121
+ runner?: CommandRunner;
122
+ fence?: ProcessFence;
123
+ connect?: (options: {
124
+ connectionFile: string;
125
+ handshakeTimeoutMs: number;
126
+ }) => Promise<ClaustrumEnrollmentConnection>;
127
+ wait?: (ms: number) => Promise<void>;
128
+ }
129
+ export interface HostDetection {
130
+ installed: boolean;
131
+ executable: string | null;
132
+ version: string | null;
133
+ directory: string;
134
+ }
135
+ export interface SetupDetection {
136
+ opencode: HostDetection & {
137
+ generation: '1' | '2' | 'ambiguous';
138
+ };
139
+ pi: HostDetection;
140
+ claustrum: {
141
+ available: boolean;
142
+ executable: string | null;
143
+ };
144
+ }
145
+ export interface SetupResult {
146
+ hosts: SetupHost[];
147
+ dryRun: boolean;
148
+ mode: 'local' | 'claustrum';
149
+ detection: SetupDetection;
150
+ }
@@ -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,9 @@
1
- export declare const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
1
+ /**
2
+ * Per-turn control beta that Claude Code sends on Opus 5.5, Sonnet 5.5,
3
+ * Fable 5.1 and Haiku 5.5. It enables effort changes carried by empty
4
+ * `role: "system"` messages on the eligible models below.
5
+ */
6
+ export declare const PER_TURN_CONTROL_BETA = "per-turn-control-2026-07-01";
2
7
  export type AdaptiveEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
3
8
  export type MidConversationEffortTransition = {
4
9
  /** Number of assistant messages preceding the user boundary for this effort. */
@@ -6,7 +11,34 @@ export type MidConversationEffortTransition = {
6
11
  effort: AdaptiveEffort;
7
12
  };
8
13
  export declare function normalizeAdaptiveEffort(value: unknown): AdaptiveEffort | undefined;
9
- export declare function usesMidConversationOutputConfig(body: Record<string, unknown>): boolean;
14
+ /**
15
+ * Models that require adaptive thinking for per-message effort: Opus 5.5
16
+ * and Sonnet 5.5, including dated and `[1m]` context-window ids. Header
17
+ * eligibility is separate; `sendsPerTurnControlBeta` follows Claude Code.
18
+ */
19
+ export declare function usesPerTurnControl(model: unknown): boolean;
20
+ /**
21
+ * Models whose OAuth requests carry `PER_TURN_CONTROL_BETA`: Opus 5.5 and
22
+ * Sonnet 5.5, plus Fable 5.1 and Haiku 5.5, which Claude Code 2.1.302 also
23
+ * sends it on. Sending the beta does not by itself make a model eligible for
24
+ * effort markers; `supportsPerMessageEffort` decides that.
25
+ */
26
+ export declare function sendsPerTurnControlBeta(model: unknown): boolean;
27
+ /**
28
+ * Whether a request may move effort changes into empty system messages.
29
+ *
30
+ * Fable 5.1 is always eligible, whatever its thinking field says. Opus 5.5
31
+ * and Sonnet 5.5 qualify only with adaptive thinking: Anthropic rejects a
32
+ * differing per-message effort with HTTP 400 on Sonnet 5.5 `between_tools`,
33
+ * and asks callers to use adaptive thinking to vary effort.
34
+ */
35
+ export declare function supportsPerMessageEffort(body: Record<string, unknown>): boolean;
36
+ /**
37
+ * The effort Anthropic applies when a request sets no `output_config.effort`:
38
+ * `medium` on Opus 5.5 and Haiku 5.5, `high` on the other models.
39
+ * A history entry without a recognized effort level uses this value.
40
+ */
41
+ export declare function defaultAdaptiveEffort(model: unknown): AdaptiveEffort;
10
42
  export declare function applyMidConversationOutputConfig(body: Record<string, unknown>, transitions: readonly MidConversationEffortTransition[]): {
11
43
  applied: boolean;
12
44
  inserted: number;
@@ -1,3 +1,4 @@
1
+ import { type OwnerOnlyOptions } from './owner-only.ts';
1
2
  export type NativeMigrationSourceRole = 'config' | 'state' | 'hostAuth' | 'routing' | 'journal';
2
3
  export interface NativeMigrationSourceSnapshot {
3
4
  readonly role: NativeMigrationSourceRole;
@@ -20,6 +21,7 @@ export declare class NativeMigrationSourceError extends Error {
20
21
  }
21
22
  interface SourceReadHooks {
22
23
  onOpened?: () => Promise<void>;
24
+ ownership?: OwnerOnlyOptions;
23
25
  }
24
26
  /**
25
27
  * Capture exact import bytes without the legacy loader's missing-entry recovery.
@@ -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
- import { type NativeDisplayProfile, type NativeVaultRuntime, type NativeVaultRuntimeOptions } from './native-vault-runtime.ts';
10
+ import { type NativeDisplayProfile, type NativeVaultQuotaPurpose, 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>;
@@ -103,11 +106,13 @@ export interface NativeAccountRuntime {
103
106
  resetBackoff(routeId: string, fence: NativeRefreshSubject | NativeCustodyReceipt, kind?: 'refresh' | 'quota' | 'all'): Promise<boolean>;
104
107
  getOrCreateAuthLineage(routeId: string, fence: NativeKnownCredentialSubject | NativeCustodyReceipt): Promise<string | undefined>;
105
108
  incrementPrimeUsage(routeId: string, fence: NativeKnownCredentialSubject | NativeCustodyReceipt, delta?: PrimeUsageDelta): Promise<boolean>;
106
- fetchQuota(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal, dispatch?: QuotaRequestDispatch): Promise<OAuthQuotaSnapshot>;
109
+ /** `purpose` applies to vault accounts only; local accounts always poll. */
110
+ fetchQuota(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal, dispatch?: QuotaRequestDispatch, purpose?: NativeVaultQuotaPurpose): Promise<OAuthQuotaSnapshot>;
107
111
  fetchProfile(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<OAuthAccountProfile>;
108
112
  /** Like fetchProfile, but returns before the profile is saved; see NativeDisplayProfile. */
109
113
  fetchProfileForDisplay(routeId: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<NativeDisplayProfile>;
110
114
  close(): void;
115
+ getSettingsPath(): Promise<string>;
111
116
  }
112
117
  /** Host instances own leases, while stores and the vault connection live until the last release. */
113
118
  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);
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Reads insula's quota cache from the vault daemon. Declared here with the
3
+ * same shape as common-auth's InsulaUsageTransport so this module's published
4
+ * declarations do not depend on common-auth.
5
+ */
6
+ export interface NativeInsulaUsageTransport {
7
+ connectionFile: string;
8
+ getUsage(): Promise<unknown>;
9
+ }
1
10
  /** Claustrum IPC operations for listing accounts, reading tokens, reporting rejection, and closing the connection. */
2
11
  export interface NativeCustodyClient {
3
12
  listScoped: (enrollmentToken?: string) => Promise<{
@@ -18,6 +27,16 @@ export interface NativeCustodyClient {
18
27
  readonly email?: string;
19
28
  readonly orgName?: string;
20
29
  }[];
30
+ /**
31
+ * How many grants this enrollment holds, and which. Undefined when the
32
+ * vault is too old to send them: unknown, never zero.
33
+ */
34
+ readonly grants: number | undefined;
35
+ readonly grantTuples: readonly {
36
+ readonly selectorKind: string;
37
+ readonly selector: string;
38
+ readonly operation: string;
39
+ }[] | undefined;
21
40
  }>;
22
41
  getScoped: (input: {
23
42
  credentialId: string;
@@ -41,6 +60,79 @@ export interface NativeCustodyClient {
41
60
  reporterSource: NativeCustodyReporterSource;
42
61
  }) => Promise<void>;
43
62
  close: () => void;
63
+ /**
64
+ * Open one vault watch that announces changes to the accounts this
65
+ * enrollment can see. Present from claustrum-client 0.12.0; without it the
66
+ * host keeps listing on its own timer.
67
+ */
68
+ watchScoped?(onNotice: (notice: NativeScopedWatchNotice) => void, options?: {
69
+ enrollmentToken?: string;
70
+ }): NativeScopedWatchHandle;
71
+ /**
72
+ * How to read insula's background quota cache on the same daemon. Present
73
+ * when the connection was made with connectClaustrumScopedClient; reading
74
+ * it opens a separate short-lived socket and never uses this connection.
75
+ */
76
+ insula?: NativeInsulaUsageTransport;
77
+ }
78
+ /**
79
+ * A vault watch notice. `view` is the same digest `listScoped` returns, so
80
+ * only a different view means the visible accounts changed. Declared here,
81
+ * like the rest of this client shape, so published declarations do not
82
+ * depend on claustrum-client or common-auth.
83
+ */
84
+ export interface NativeScopedWatchNotice {
85
+ readonly kind: string;
86
+ readonly epoch: string;
87
+ readonly seq: number;
88
+ readonly view: string;
89
+ }
90
+ /**
91
+ * How a vault watch ended. `refused` carries the vault's refusal of the
92
+ * confirming account listing (a revoked enrollment answers `not_found`);
93
+ * `unsupported` means the vault does not know the watch method.
94
+ */
95
+ export type NativeScopedWatchEnd = {
96
+ readonly kind: 'refused';
97
+ readonly error: unknown;
98
+ } | {
99
+ readonly kind: 'transport_lost';
100
+ readonly error: unknown;
101
+ } | {
102
+ readonly kind: 'ended' | 'not_accepting' | 'unsupported' | 'stopped';
103
+ };
104
+ export interface NativeScopedWatchHandle {
105
+ stop(): void;
106
+ readonly closed: Promise<NativeScopedWatchEnd>;
107
+ }
108
+ /**
109
+ * How the host currently learns about account changes. `watching`: a vault
110
+ * watch is open, so the host's list timer only needs to run as a slow safety
111
+ * net. `polling` and `fallback`: no watch is open, so the host lists at its
112
+ * usual pace.
113
+ */
114
+ export type NativeRosterWatchMode = 'watching' | 'polling' | 'fallback';
115
+ export interface NativeRosterWatchOptions {
116
+ /**
117
+ * Run the host's discovery and roster publication. Called when a notice
118
+ * shows the visible accounts changed since the roster the host holds; one
119
+ * call at a time, and notices that arrive meanwhile earn at most one more.
120
+ */
121
+ onView: (view: string) => unknown;
122
+ /** The view of the roster the host currently holds, if any. */
123
+ view?: () => string | undefined;
124
+ onMode?: (mode: NativeRosterWatchMode) => void;
125
+ /**
126
+ * The vault refused the watch and its confirming listing. Kept receipts are
127
+ * already dropped, as a refused listing drops them.
128
+ */
129
+ onRefused?: (error: unknown) => void;
130
+ onError?: (error: unknown) => void;
131
+ }
132
+ export interface NativeRosterWatch {
133
+ readonly mode: NativeRosterWatchMode;
134
+ /** Stop the watch and its timers. Safe to call more than once. */
135
+ close(): void;
44
136
  }
45
137
  export type NativeCustodyReporterSource = 'direct' | 'relay_status_field' | 'relay_message_parse';
46
138
  export interface NativeCustodyLogger {
@@ -57,6 +149,12 @@ export interface NativeCustodyOptions {
57
149
  env?: NodeJS.ProcessEnv;
58
150
  now?: () => number;
59
151
  logger?: NativeCustodyLogger;
152
+ /**
153
+ * Timer functions for the custody's outage probe and roster watch retries.
154
+ * Defaults to the global ones; tests pass their own.
155
+ */
156
+ setTimeout?: typeof globalThis.setTimeout;
157
+ clearTimeout?: typeof globalThis.clearTimeout;
60
158
  }
61
159
  export interface NativeCustodyIdentity {
62
160
  readonly credentialId: string;
@@ -74,6 +172,7 @@ export interface NativeCustodyReceipt {
74
172
  readonly recordVersion: number;
75
173
  readonly expiresAtMs: number | null;
76
174
  readonly accessToken: string;
175
+ readonly fromKeptReceipt?: true;
77
176
  }
78
177
  export interface NativeCustodyInventory {
79
178
  readonly view: string;
@@ -89,6 +188,20 @@ export interface NativeCustodyInventory {
89
188
  readonly credentialId?: string;
90
189
  readonly reason: 'empty credential id' | 'duplicate credential id' | 'blank account identity' | 'empty state';
91
190
  }[];
191
+ /**
192
+ * What this host's enrollment is granted, as the vault's list reply named
193
+ * it. It explains an empty listing: `grants === 0` means no grant at all,
194
+ * while `grants > 0` means a grant that reaches no credential. Undefined
195
+ * means unknown (the vault predates these fields), never zero grants.
196
+ */
197
+ readonly grantReach?: {
198
+ readonly grants: number;
199
+ readonly tuples: readonly {
200
+ readonly selectorKind: string;
201
+ readonly selector: string;
202
+ readonly operation: string;
203
+ }[];
204
+ };
92
205
  }
93
206
  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
207
  export declare class NativeCustodyError extends Error {
@@ -108,6 +221,23 @@ export interface NativeCustody {
108
221
  authorize: (identity: NativeCustodyIdentity, signal?: AbortSignal) => Promise<NativeCustodyReceipt>;
109
222
  reportFailure: (receipt: NativeCustodyReceipt, status: number, reporterSource: NativeCustodyReporterSource) => Promise<void>;
110
223
  prepareRetry: (served: NativeCustodyReceipt, signal?: AbortSignal) => Promise<NativeCustodyRetry>;
224
+ /** The shared connection's insula transport, connecting first if needed; undefined when the client has none. */
225
+ insulaTransport: () => Promise<NativeInsulaUsageTransport | undefined>;
226
+ retain: (rows: readonly (NativeCustodyIdentity & {
227
+ enabled: boolean;
228
+ state: string;
229
+ })[]) => void;
230
+ forget: (credentialId: string) => void;
231
+ keptReceiptState: () => Readonly<{
232
+ active: boolean;
233
+ since: number | null;
234
+ }>;
235
+ /**
236
+ * Watch the vault for account changes over the shared connection instead
237
+ * of relying on the host's list timer alone. A client or vault without the
238
+ * watch reports `fallback`. Closing the custody closes every watch.
239
+ */
240
+ watchRoster: (options: NativeRosterWatchOptions) => NativeRosterWatch;
111
241
  close: () => void;
112
242
  }
113
243
  /** Share a lazy Claustrum connection; each authorize call reads a fresh enrollment token and OAuth receipt. */
@@ -1,2 +1,6 @@
1
+ import { enrollmentAuthority, readClaustrumEnrollmentStatus } from "./internal-types/claustrum/index.js";
1
2
  /** 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'>;
3
+ export declare function readNativeEnrollmentMode(host: 'opencode' | 'pi', env?: NodeJS.ProcessEnv, dependencies?: {
4
+ enrollmentAuthority: typeof enrollmentAuthority;
5
+ readClaustrumEnrollmentStatus: typeof readClaustrumEnrollmentStatus;
6
+ }): Promise<'local' | 'claustrum'>;
@@ -1,3 +1,4 @@
1
1
  import { type NativeHostAuthEntryInspection } from './native-host-auth.ts';
2
+ import { type OwnerOnlyOptions } from './owner-only.ts';
2
3
  /** 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']>;
4
+ export declare function readNativeHostAuthKind(host: 'opencode' | 'pi', path: string, ownership?: OwnerOnlyOptions): Promise<NativeHostAuthEntryInspection['kind']>;
@@ -1,3 +1,4 @@
1
+ import { type PublicationOptions } from './publication-rename.ts';
1
2
  export interface NativeHostAuthWriteInput {
2
3
  readonly host: 'opencode' | 'pi';
3
4
  /**
@@ -16,6 +17,7 @@ export interface NativeHostAuthWriteInput {
16
17
  readonly processFence: () => Promise<void>;
17
18
  }
18
19
  export interface NativeHostAuthWriteHooks {
20
+ readonly publication?: PublicationOptions;
19
21
  readonly beforeRecheck?: () => Promise<void>;
20
22
  readonly beforeRename?: () => Promise<void>;
21
23
  readonly afterRename?: () => Promise<void>;
@@ -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';