@cortexkit/anthropic-auth-core 2.2.1 → 2.2.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.
- package/dist/claude-code.d.ts +2 -1
- package/dist/constants.d.ts +5 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1575 -913
- package/dist/internal-types/claustrum/consumer.d.ts +3 -1
- package/dist/internal-types/claustrum/enrollment.d.ts +5 -0
- package/dist/internal-types/claustrum/index.d.ts +1 -0
- package/dist/internal-types/claustrum/quota-writer.d.ts +18 -0
- package/dist/internal-types/claustrum/roster.d.ts +18 -2
- package/dist/internal-types/fs/private-files.d.ts +2 -0
- package/dist/internal-types/fs/with-lock.d.ts +1 -0
- package/dist/internal-types/quota/format.d.ts +19 -0
- package/dist/internal-types/quota/index.d.ts +3 -3
- package/dist/internal-types/quota/map.d.ts +24 -1
- package/dist/internal-types/quota/merge.d.ts +6 -1
- package/dist/internal-types/quota/projection.d.ts +3 -1
- package/dist/internal-types/setup/enroll.d.ts +34 -0
- package/dist/internal-types/setup/index.d.ts +1 -0
- package/dist/internal-types/setup/process-fence.d.ts +14 -0
- package/dist/internal-types/setup/types.d.ts +5 -0
- package/dist/mid-conversation-output-config.d.ts +19 -15
- package/dist/model-capabilities.d.ts +136 -0
- package/dist/models.d.ts +28 -59
- package/dist/native-enrollment-authority.d.ts +19 -0
- package/dist/native-ui.d.ts +10 -1
- package/dist/native-vault-runtime.d.ts +1 -1
- package/dist/turn-end-note.d.ts +4 -3
- package/package.json +2 -2
|
@@ -169,8 +169,10 @@ export declare class ClaustrumConsumer<Q = QuotaObservation> {
|
|
|
169
169
|
* a served credential (an insula reading from `cachedInsulaQuotaForRoute`).
|
|
170
170
|
* It lands only while the route is still bound to that known account, so no
|
|
171
171
|
* credential fetch is needed and a replaced account's reading is dropped.
|
|
172
|
-
*
|
|
172
|
+
* Memory updates immediately; durable publication is detached and coalesced.
|
|
173
173
|
*/
|
|
174
174
|
recordAccountQuota(routeId: string, accountIdentity: string, observation: QuotaObservation): Promise<boolean>;
|
|
175
175
|
close(): void;
|
|
176
|
+
/** Close immediately; the last consumer also waits for the writer's bounded drain. */
|
|
177
|
+
dispose(): Promise<void>;
|
|
176
178
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { type ClaustrumClientOptions as ClaustrumEnrollmentClientOptions, type EnrollmentPollOutcome, type EnrollmentTokenFile, writeEnrollmentTokenFile } from '@cortexkit/claustrum-client';
|
|
2
|
+
/**
|
|
3
|
+
* The code a vault without the enrollment ceremony answers a proposal with.
|
|
4
|
+
* Setup reports it as "this vault cannot connect plugins" instead of waiting.
|
|
5
|
+
*/
|
|
6
|
+
export declare const UNSUPPORTED_ENROLLMENT_CODE = "unknown_method";
|
|
2
7
|
/**
|
|
3
8
|
* Codes the vault's closed enrollment-refusal vocabulary marks permanent. The
|
|
4
9
|
* client labels some module error frames transient/retry regardless, so the
|
|
@@ -9,6 +9,7 @@ export { ClaustrumConsumerError, type ClaustrumConsumerFailureKind, type Claustr
|
|
|
9
9
|
export { assertHostSlotMatchesMode, assertNotCustodyPlaceholder, CUSTODY_PLACEHOLDER_PREFIX, classifyHostSlot, custodyPlaceholder, custodyPlaceholderKey, type HostSlotContent, isCustodyPlaceholder, isCustodyPlaceholderValue, } from './host-slot.js';
|
|
10
10
|
export { acquireInsulaQuotaSource, type InsulaQuotaContext, type InsulaQuotaLookup, type InsulaQuotaMiss, type InsulaQuotaOptions, type InsulaQuotaReading, type InsulaQuotaResult, type InsulaQuotaSource, type InsulaUsageEntry, type InsulaUsageTransport, type InsulaUsageWatch, type InsulaUsageWindow, type InsulaWatchOptions, } from './insula.js';
|
|
11
11
|
export { acceptAccount, type DeclinedAccount, declineAccount, isDeclined, } from './interlock.js';
|
|
12
|
+
export { drainVaultQuota } from './quota-writer.js';
|
|
12
13
|
export { type AccountMapper, acceptVaultRoute, DEFAULT_ROUTE_PREFIX, declineVaultRoute, type MutateVaultRosterOptions, mutateVaultRoster, type ProjectionOptions, projectVaultRoster, type QuotaReceipt, readVaultRoster, recordVaultAccountQuota, recordVaultQuota, refreshVaultRoster, resolveVaultPrimary, type VaultPrimary, type VaultPrimaryBinding, type VaultPrimaryUnavailableReason, type VaultRosterFile, type VaultRosterLockContext, type VaultRosterRow, vaultRoutingRows, } from './roster.js';
|
|
13
14
|
export { type ChangeNotice, ChangeNoticeReader, RESUBSCRIBE_BACKOFF_MS, SAFETY_POLL_MS, ScopedRosterWatch, type ScopedRosterWatchOptions, type ScopedWatchEnd, type ScopedWatchHandle, type ScopedWatchNoticeShape, type ScopedWatchSource, WATCH_RETRY_MS, type WatchMode, } from './watch.js';
|
|
14
15
|
/**
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type QuotaObservation } from '../quota/index.js';
|
|
2
|
+
import { type QuotaReceipt, type VaultRosterFile } from './roster.js';
|
|
3
|
+
export type VaultQuotaPublication = {
|
|
4
|
+
routeId: string;
|
|
5
|
+
accountIdentity?: string;
|
|
6
|
+
receipt?: QuotaReceipt;
|
|
7
|
+
observation: QuotaObservation;
|
|
8
|
+
};
|
|
9
|
+
type Listener = (publication: VaultQuotaPublication) => void;
|
|
10
|
+
/** Retain the shared writer; the last consumer's close drains it. */
|
|
11
|
+
export declare function retainVaultQuotaWriter(path: string, listener: Listener): () => Promise<void>;
|
|
12
|
+
/** Enqueue without filesystem work; each quota field retains its own receipt fence. */
|
|
13
|
+
export declare function enqueueVaultQuota(path: string, publication: VaultQuotaPublication): Promise<boolean>;
|
|
14
|
+
/** Overlay uncommitted observations when a consumer reloads the durable roster. */
|
|
15
|
+
export declare function pendingVaultQuota(path: string, roster: VaultRosterFile | undefined): VaultRosterFile | undefined;
|
|
16
|
+
/** Wait at most timeoutMs for detached publication; shutdown loss is acceptable. */
|
|
17
|
+
export declare function drainVaultQuota(path: string, timeoutMs?: number): Promise<void>;
|
|
18
|
+
export {};
|
|
@@ -2,6 +2,8 @@ import { type QuotaMap, type QuotaObservation } from '../quota/index.js';
|
|
|
2
2
|
import type { RoutingRow } from '../routing/index.js';
|
|
3
3
|
import type { ClaustrumScopedAttempt, ClaustrumScopedCustody, SkippedVaultRecord, VaultCredential, VaultCredentialType, VaultInventory } from './custody.js';
|
|
4
4
|
import { type DeclinedAccount } from './interlock.js';
|
|
5
|
+
import { type VaultQuotaPublication } from './quota-writer.js';
|
|
6
|
+
export { drainVaultQuota } from './quota-writer.js';
|
|
5
7
|
/**
|
|
6
8
|
* One vault account as the pool sees it. It carries no bearer material: the
|
|
7
9
|
* access token is fetched from the vault for every send. Several vault
|
|
@@ -91,6 +93,7 @@ export interface VaultRosterLockContext {
|
|
|
91
93
|
assertOwned: () => Promise<void>;
|
|
92
94
|
}
|
|
93
95
|
export interface MutateVaultRosterOptions {
|
|
96
|
+
signal?: AbortSignal;
|
|
94
97
|
/**
|
|
95
98
|
* Runs when the new roster is fully staged on disk, immediately before the
|
|
96
99
|
* rename that publishes it, so a caller can confirm a lease of its own at
|
|
@@ -127,7 +130,10 @@ export type QuotaReceipt = Pick<ClaustrumScopedAttempt, 'credentialId' | 'accoun
|
|
|
127
130
|
* write is fenced on the receipt the reading was taken with: it lands only
|
|
128
131
|
* while the row still holds that receipt's credential (as representative or
|
|
129
132
|
* alias) and account, so a slow read for a replaced account can never land on
|
|
130
|
-
* its successor.
|
|
133
|
+
* its successor. Resolves false when the fence refuses the reading against the
|
|
134
|
+
* roster as it stands now (on disk, plus readings this process has not
|
|
135
|
+
* written yet), and true once the reading is queued for the next write. The
|
|
136
|
+
* write applies the fence again, so a rebind between the two still refuses.
|
|
131
137
|
*/
|
|
132
138
|
export declare function recordVaultQuota(path: string, input: QuotaReceipt & {
|
|
133
139
|
routeId: string;
|
|
@@ -139,19 +145,28 @@ export declare function recordVaultQuota(path: string, input: QuotaReceipt & {
|
|
|
139
145
|
* lands only while the row is still bound to that exact known account, so a
|
|
140
146
|
* reading taken before a replacement never reaches the successor. Unlike
|
|
141
147
|
* `recordVaultQuota` it never binds an account: a row without a known account
|
|
142
|
-
* is refused.
|
|
148
|
+
* is refused. Resolves false when the row is not bound to that account now,
|
|
149
|
+
* and true once the reading is queued, as `recordVaultQuota` does.
|
|
143
150
|
*/
|
|
144
151
|
export declare function recordVaultAccountQuota(path: string, input: {
|
|
145
152
|
routeId: string;
|
|
146
153
|
accountIdentity: string;
|
|
147
154
|
observation: QuotaObservation;
|
|
148
155
|
}): Promise<boolean>;
|
|
156
|
+
/** Apply the same identity fence to memory overlays and durable quota batches. */
|
|
157
|
+
export declare function applyVaultQuota(current: VaultRosterFile | undefined, input: VaultQuotaPublication): {
|
|
158
|
+
roster: VaultRosterFile | undefined;
|
|
159
|
+
kept: boolean;
|
|
160
|
+
};
|
|
161
|
+
export declare function forgetPendingVaultDiscovery(path: string): void;
|
|
149
162
|
/**
|
|
150
163
|
* Discover and commit the roster. The lease covers the list call and the
|
|
151
164
|
* commit, not just the write: an opaque view cannot tell a delayed old reply
|
|
152
165
|
* from a newer one, so a run that lost its lease is refused at commit. A
|
|
153
166
|
* failed list, or custody switching off mid-run, never writes anything; a
|
|
154
167
|
* peer holding the lease means its last committed roster is served instead.
|
|
168
|
+
* A write-lock timeout keeps the discovered inventory for the next poll,
|
|
169
|
+
* unless a peer has superseded its base view in the meantime.
|
|
155
170
|
*/
|
|
156
171
|
export declare function refreshVaultRoster(options: {
|
|
157
172
|
path: string;
|
|
@@ -159,6 +174,7 @@ export declare function refreshVaultRoster(options: {
|
|
|
159
174
|
isActive?: () => boolean | Promise<boolean>;
|
|
160
175
|
signal?: AbortSignal;
|
|
161
176
|
projection?: ProjectionOptions | (() => ProjectionOptions);
|
|
177
|
+
onInventory?: (inventory: VaultInventory) => void;
|
|
162
178
|
}): Promise<VaultRosterFile | undefined>;
|
|
163
179
|
/**
|
|
164
180
|
* A host-owned main account as last verified from the vault: the plugin's
|
|
@@ -5,6 +5,8 @@ type Backend = typeof import('@cortexkit/private-files');
|
|
|
5
5
|
type Kind = 'file' | 'directory';
|
|
6
6
|
/** Tests inject a backend here; production always imports the private-files package. */
|
|
7
7
|
export declare function setPrivateFilesBackendForTest(api?: Backend): void;
|
|
8
|
+
/** The fixed `reason` of a refusal because the Windows native addon did not load. */
|
|
9
|
+
export declare const PRIVATE_FILES_UNAVAILABLE_REASON = "native-addon-unavailable";
|
|
8
10
|
export declare class PrivateFileError extends Error {
|
|
9
11
|
readonly path: string;
|
|
10
12
|
readonly stage: string;
|
|
@@ -28,6 +28,7 @@ export interface LockOptions {
|
|
|
28
28
|
ttlMs: number;
|
|
29
29
|
timeoutMs: number;
|
|
30
30
|
renew?: boolean;
|
|
31
|
+
signal?: AbortSignal;
|
|
31
32
|
onStep?: Parameters<typeof acquireRefreshFileLock>[0]['onStep'];
|
|
32
33
|
onRenewalTimer?: Parameters<typeof acquireRefreshFileLock>[0]['onRenewalTimer'];
|
|
33
34
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type QuotaCredits } from './map.js';
|
|
1
2
|
import type { ProjectedLimit, ProjectedQuota } from './projection.js';
|
|
2
3
|
/** A reading older than this is marked with its age. */
|
|
3
4
|
export declare const QUOTA_STALE_AFTER_MS: number;
|
|
@@ -31,6 +32,13 @@ export interface QuotaWindowPart {
|
|
|
31
32
|
kind: 'window' | 'budget';
|
|
32
33
|
/** The display name of a quota window, or `credits` for the budget. */
|
|
33
34
|
name: string;
|
|
35
|
+
/**
|
|
36
|
+
* The label the narrow line gives this item: an account-wide window keeps
|
|
37
|
+
* its name (`5h`), a model-scoped window reads as its model's short name
|
|
38
|
+
* (`Fa` for Fable, extended until names in the same reading differ), and
|
|
39
|
+
* the budget reads `cr`. For layouts too narrow for the full name.
|
|
40
|
+
*/
|
|
41
|
+
short: string;
|
|
34
42
|
/** The shared figure wording, including `credits` for budget figures. */
|
|
35
43
|
figure: string;
|
|
36
44
|
/** The unrounded remaining percentage, clamped to 0–100, when known. */
|
|
@@ -84,3 +92,14 @@ export declare function quotaTextParts(quota: ProjectedQuota | undefined, option
|
|
|
84
92
|
* provider answered without a limit for any window.
|
|
85
93
|
*/
|
|
86
94
|
export declare function formatQuota(quota: ProjectedQuota | undefined, options: QuotaTextOptions): string;
|
|
95
|
+
/**
|
|
96
|
+
* Prepaid credits as one short value, worded as the official Codex client's
|
|
97
|
+
* status view words them: `Unlimited` for unlimited credits, `<n> credits`
|
|
98
|
+
* for a finite positive balance (rounded to a whole number), `Available` when
|
|
99
|
+
* the account has credits but no usable balance was reported, and undefined
|
|
100
|
+
* when the account has no credits (or `credits` is undefined), so a caller
|
|
101
|
+
* shows no credits row at all. Unlimited wins even when `hasCredits` is false.
|
|
102
|
+
* No other formatter adds this text; a caller that wants a credits row asks
|
|
103
|
+
* for it.
|
|
104
|
+
*/
|
|
105
|
+
export declare function quotaCreditsText(credits: Pick<QuotaCredits, 'hasCredits' | 'unlimited' | 'balance'> | undefined): string | undefined;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type { QuotaCodec } from './codec.js';
|
|
2
2
|
export { quotaCodec } from './codec.js';
|
|
3
3
|
export type { QuotaParts, QuotaTextForm, QuotaTextOptions, QuotaWindowPart, } from './format.js';
|
|
4
|
-
export { formatQuota, isQuotaStale, NO_LIMITS_REPORTED, NO_QUOTA_READING, QUOTA_STALE_AFTER_MS, quotaTextParts, quotaWindowName, quotaWindowParts, } from './format.js';
|
|
5
|
-
export type { CreditBudgetCleared, CreditBudgetEntry, CreditBudgetReading, QuotaAbsentEntry, QuotaCounter, QuotaEntry, QuotaMap, QuotaReadingEntry, QuotaRetiredEntry, } from './map.js';
|
|
6
|
-
export { ALL_SCOPE, DEFAULT_REQUIRED_LABELS, decodeQuotaMap, emptyQuotaMap, isQuotaMap, } from './map.js';
|
|
4
|
+
export { formatQuota, isQuotaStale, NO_LIMITS_REPORTED, NO_QUOTA_READING, QUOTA_STALE_AFTER_MS, quotaCreditsText, quotaTextParts, quotaWindowName, quotaWindowParts, } from './format.js';
|
|
5
|
+
export type { CreditBudgetCleared, CreditBudgetEntry, CreditBudgetReading, QuotaAbsentEntry, QuotaCounter, QuotaCredits, QuotaEntry, QuotaMap, QuotaReadingEntry, QuotaRetiredEntry, } from './map.js';
|
|
6
|
+
export { ALL_SCOPE, DEFAULT_REQUIRED_LABELS, decodeQuotaMap, emptyQuotaMap, isQuotaCredits, isQuotaMap, } from './map.js';
|
|
7
7
|
export type { ObservedBudget, ObservedPair, ObservedReading, QuotaObservation, } from './merge.js';
|
|
8
8
|
export { isQuotaObservation, mergeQuotaObservation, QuotaCodecError, } from './merge.js';
|
|
9
9
|
export type { ExhaustionReset, ProjectedBudget, ProjectedLimit, ProjectedQuota, QuotaGroup, } from './projection.js';
|
|
@@ -48,12 +48,30 @@ export interface QuotaCounter {
|
|
|
48
48
|
value: number;
|
|
49
49
|
checkedAt: number;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Prepaid credits a provider account holds beside its rate-limit windows (for
|
|
53
|
+
* example a ChatGPT workspace's credits, which keep requests working after a
|
|
54
|
+
* window is used up). This is a state, not a count or the spend budget: the
|
|
55
|
+
* account has credits or not, they may be unlimited, and the provider may
|
|
56
|
+
* report a balance. It carries its own observation time.
|
|
57
|
+
*/
|
|
58
|
+
export interface QuotaCredits {
|
|
59
|
+
hasCredits: boolean;
|
|
60
|
+
unlimited: boolean;
|
|
61
|
+
/** The balance the provider reported, when it reported one. */
|
|
62
|
+
balance?: number;
|
|
63
|
+
/** The provider's verdict that the overage allowance is used up. */
|
|
64
|
+
overageLimitReached?: boolean;
|
|
65
|
+
checkedAt: number;
|
|
66
|
+
}
|
|
51
67
|
export interface QuotaMap {
|
|
52
68
|
limits: QuotaEntry[];
|
|
53
69
|
/** Absent means no observation has reported on the budget yet. */
|
|
54
70
|
budget?: CreditBudgetEntry;
|
|
55
71
|
/** Provider-named counts, each with its own observation time. */
|
|
56
72
|
counters?: Record<string, QuotaCounter>;
|
|
73
|
+
/** Absent means no observation has reported on prepaid credits yet. */
|
|
74
|
+
credits?: QuotaCredits;
|
|
57
75
|
}
|
|
58
76
|
export declare function emptyQuotaMap(): QuotaMap;
|
|
59
77
|
/** The time an entry speaks for: its reading, retirement or absence time. */
|
|
@@ -61,9 +79,14 @@ export declare function entryTime(entry: QuotaEntry): number;
|
|
|
61
79
|
export declare function limitKey(scope: string, label: string): string;
|
|
62
80
|
export declare function isCreditBudgetEntry(value: unknown): value is CreditBudgetEntry;
|
|
63
81
|
export declare function isQuotaCounters(value: unknown): value is Record<string, QuotaCounter>;
|
|
82
|
+
/** True when `value` is a well-formed prepaid-credits record. */
|
|
83
|
+
export declare function isQuotaCredits(value: unknown): value is QuotaCredits;
|
|
64
84
|
/** Keep usable counters without letting one malformed count hide a quota map. */
|
|
65
85
|
export declare function readQuotaCounters(value: unknown): Record<string, QuotaCounter> | undefined;
|
|
66
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* Decode persisted quota, dropping malformed counters or a malformed credits
|
|
88
|
+
* record but not limit or budget evidence.
|
|
89
|
+
*/
|
|
67
90
|
export declare function decodeQuotaMap(value: unknown): QuotaMap | undefined;
|
|
68
91
|
/**
|
|
69
92
|
* True when `value` is a well-formed quota map. Unrecognised top-level keys
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QuotaCounter, type QuotaMap } from './map.js';
|
|
1
|
+
import { type QuotaCounter, type QuotaCredits, type QuotaMap } from './map.js';
|
|
2
2
|
export interface ObservedReading {
|
|
3
3
|
/** Defaults to `all`. */
|
|
4
4
|
scope?: string;
|
|
@@ -34,6 +34,11 @@ export interface QuotaObservation {
|
|
|
34
34
|
budget?: ObservedBudget;
|
|
35
35
|
/** Each named count uses its own time, independently of limits and budget. */
|
|
36
36
|
counters?: Record<string, QuotaCounter>;
|
|
37
|
+
/**
|
|
38
|
+
* Prepaid credits, judged by their own time independently of limits, budget
|
|
39
|
+
* and counters. Absent means the observation says nothing about credits.
|
|
40
|
+
*/
|
|
41
|
+
credits?: QuotaCredits;
|
|
37
42
|
}
|
|
38
43
|
/** Thrown by `mergeQuotaObservation` when either argument is malformed. */
|
|
39
44
|
export declare class QuotaCodecError extends TypeError {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QuotaCounter, type QuotaMap } from './map.js';
|
|
1
|
+
import { type QuotaCounter, type QuotaCredits, type QuotaMap } from './map.js';
|
|
2
2
|
export interface ProjectedLimit {
|
|
3
3
|
scope: string;
|
|
4
4
|
label: string;
|
|
@@ -40,6 +40,8 @@ export interface ProjectedQuota {
|
|
|
40
40
|
/** Present only when the stored budget is a reading, not cleared. */
|
|
41
41
|
budget?: ProjectedBudget;
|
|
42
42
|
counters?: Record<string, QuotaCounter>;
|
|
43
|
+
/** The stored prepaid credits, unchanged in every scope. */
|
|
44
|
+
credits?: QuotaCredits;
|
|
43
45
|
/**
|
|
44
46
|
* The named groups the windows belong to, in the order the plugin lists
|
|
45
47
|
* them. Set only by a plugin whose windows all belong to such groups; the
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type MenuTerminal } from '../auth-menu/terminal.js';
|
|
2
|
+
import type { SetupHost, SetupIO, SetupPlugin } from './types.js';
|
|
3
|
+
/** Fixed text: no version, host or account detail, so it is safe to print anywhere. */
|
|
4
|
+
export declare const UNSUPPORTED_VAULT_MESSAGE = "This Claustrum vault does not support connecting plugins yet, so setup cannot connect to it. Run setup without --claustrum to use local accounts.";
|
|
5
|
+
/**
|
|
6
|
+
* The longest setup waits, in total, for the vault to create the enrollment
|
|
7
|
+
* request and for an operator to approve it. It matches the wait setup always
|
|
8
|
+
* had (300 one-second polls), but is now measured on the clock: a vault that
|
|
9
|
+
* answers each request slowly can no longer stretch it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ENROLLMENT_WAIT_MS = 300000;
|
|
12
|
+
/** Why a host's enrollment ended without a token. */
|
|
13
|
+
export type HostNotEnrolledReason = 'connection-failed' | 'unsupported-vault' | 'request-not-created' | 'approval-pending' | 'refused' | 'invalid-request' | 'incomplete';
|
|
14
|
+
/**
|
|
15
|
+
* Thrown when the enrollment ended without writing the host's token: the vault
|
|
16
|
+
* could not be reached, it cannot enroll plugins, it refused the request, it
|
|
17
|
+
* never created one, approval never came before setup stopped waiting, or
|
|
18
|
+
* the enrollment failed in some other way (`incomplete`).
|
|
19
|
+
* Setup can then report the host as not connected without reading its files.
|
|
20
|
+
* The message is fixed text built only from vetted values, never from what
|
|
21
|
+
* the vault or client threw. `lastErrorCode` is the last enrollment error code
|
|
22
|
+
* setup saw, from the vault or from the client's transport (for example
|
|
23
|
+
* `transport_error`), for diagnostics; it carries no secret.
|
|
24
|
+
*/
|
|
25
|
+
export declare class HostNotEnrolledError extends Error {
|
|
26
|
+
readonly reason: HostNotEnrolledReason;
|
|
27
|
+
readonly lastErrorCode?: string;
|
|
28
|
+
constructor(message: string, details: {
|
|
29
|
+
reason: HostNotEnrolledReason;
|
|
30
|
+
lastErrorCode?: string;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Enroll an independently revocable host; plugin callbacks choose its credential store and account permissions. */
|
|
34
|
+
export declare function connectSetupHost(plugin: SetupPlugin, host: SetupHost, io: SetupIO, terminal: MenuTerminal, fence: () => Promise<void>): Promise<void>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { AMBIGUOUS_OPENCODE_MESSAGE, runSetup } from './command.js';
|
|
2
2
|
export { SetupCommandError, setupEnrollment } from './command-error.js';
|
|
3
3
|
export { detectHosts, detectOpenCodeGeneration, findExecutableOnPath, openCodeDesktopMarkers, } from './detect.js';
|
|
4
|
+
export { ENROLLMENT_WAIT_MS, HostNotEnrolledError, type HostNotEnrolledReason, UNSUPPORTED_VAULT_MESSAGE, } from './enroll.js';
|
|
4
5
|
export { assertHostsStopped, createProcessFence, listSetupProcesses, ProcessFenceViolationError, ProcessInspectionError, type ProcessInspectionStep, } from './process-fence.js';
|
|
5
6
|
export { type PlannedWrite, planOpenCodeRegistration, registerOpenCode, registerPi, updatePluginConfig, } from './register.js';
|
|
6
7
|
export type { CommandResult, CommandRunner, HostDetection, OpenCodeGeneration, ProcessFence, SetupCallbackContext, SetupDetection, SetupEnrollmentOutcome, SetupEnvironment, SetupFileSystem, SetupHost, SetupHostEnrollment, SetupIO, SetupPlugin, SetupResult, } from './types.js';
|
|
@@ -33,11 +33,25 @@ export declare function listSetupProcesses(runner?: CommandRunner, options?: {
|
|
|
33
33
|
onStep?: (details: ProcessInspectionStep) => void;
|
|
34
34
|
/** False skips the Windows PowerShell query for Node and Bun command lines. */
|
|
35
35
|
inspectRuntimes?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The process to leave out, the running setup itself. Defaults to
|
|
38
|
+
* `process.pid`; tests pass a value no listed process can have, because in
|
|
39
|
+
* a container this process can hold any small PID a fixture uses.
|
|
40
|
+
*/
|
|
41
|
+
selfPid?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Windows only: answer with one CIM query for the images a fence cares
|
|
44
|
+
* about (host programs, Node and Bun), returning image name, PID and
|
|
45
|
+
* command line together, instead of `tasklist` followed by a second CIM
|
|
46
|
+
* query. The result lists only those processes.
|
|
47
|
+
*/
|
|
48
|
+
hostImagesOnly?: boolean;
|
|
36
49
|
}): Promise<Array<{
|
|
37
50
|
pid: number;
|
|
38
51
|
command: string;
|
|
39
52
|
}>>;
|
|
40
53
|
export declare function createProcessFence(runner?: CommandRunner, options?: {
|
|
41
54
|
platform?: string;
|
|
55
|
+
selfPid?: number;
|
|
42
56
|
}): ProcessFence;
|
|
43
57
|
export declare function assertHostsStopped(fence: ProcessFence, env?: SetupEnvironment): Promise<void>;
|
|
@@ -125,6 +125,11 @@ export interface SetupIO {
|
|
|
125
125
|
handshakeTimeoutMs: number;
|
|
126
126
|
}) => Promise<ClaustrumEnrollmentConnection>;
|
|
127
127
|
wait?: (ms: number) => Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Monotonic milliseconds that bound the enrollment wait. Defaults to
|
|
130
|
+
* `performance.now`; tests pair it with `wait` to run a fake clock.
|
|
131
|
+
*/
|
|
132
|
+
now?: () => number;
|
|
128
133
|
}
|
|
129
134
|
export interface HostDetection {
|
|
130
135
|
installed: boolean;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { PER_TURN_CONTROL_BETA } from './model-capabilities.ts';
|
|
1
2
|
/**
|
|
2
|
-
* Per-turn control beta that Claude Code sends on
|
|
3
|
-
*
|
|
3
|
+
* Per-turn control beta that Claude Code sends on the models whose
|
|
4
|
+
* capability rows list it. It enables effort changes carried by empty
|
|
4
5
|
* `role: "system"` messages on the eligible models below.
|
|
5
6
|
*/
|
|
6
|
-
export
|
|
7
|
+
export { PER_TURN_CONTROL_BETA };
|
|
7
8
|
export type AdaptiveEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
8
9
|
export type MidConversationEffortTransition = {
|
|
9
10
|
/** Number of assistant messages preceding the user boundary for this effort. */
|
|
@@ -12,30 +13,33 @@ export type MidConversationEffortTransition = {
|
|
|
12
13
|
};
|
|
13
14
|
export declare function normalizeAdaptiveEffort(value: unknown): AdaptiveEffort | undefined;
|
|
14
15
|
/**
|
|
15
|
-
* Models that require adaptive thinking for per-message effort
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Models that require adaptive thinking for per-message effort (capability
|
|
17
|
+
* `effortMarkers: "with-adaptive-thinking"`: Opus 5.5 and Sonnet 5.5),
|
|
18
|
+
* including dated and `[1m]` context-window ids. Header eligibility is
|
|
19
|
+
* separate; `sendsPerTurnControlBeta` follows Claude Code.
|
|
18
20
|
*/
|
|
19
21
|
export declare function usesPerTurnControl(model: unknown): boolean;
|
|
20
22
|
/**
|
|
21
|
-
* Models whose OAuth requests carry `PER_TURN_CONTROL_BETA`:
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* effort markers; `supportsPerMessageEffort` decides that.
|
|
23
|
+
* Models whose OAuth requests carry `PER_TURN_CONTROL_BETA`: those whose
|
|
24
|
+
* Claude Code main beta list includes it (Opus 5.5, Sonnet 5.5, Fable 5.1 and
|
|
25
|
+
* Haiku 5.5 in Claude Code 2.1.302). Sending the beta does not by itself make
|
|
26
|
+
* a model eligible for effort markers; `supportsPerMessageEffort` decides that.
|
|
25
27
|
*/
|
|
26
28
|
export declare function sendsPerTurnControlBeta(model: unknown): boolean;
|
|
27
29
|
/**
|
|
28
30
|
* Whether a request may move effort changes into empty system messages.
|
|
29
31
|
*
|
|
30
|
-
* Fable 5.1
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* Models with `effortMarkers: "always"` (Fable 5.1) are always eligible,
|
|
33
|
+
* whatever the thinking field says. Models with `"with-adaptive-thinking"`
|
|
34
|
+
* (Opus 5.5, Sonnet 5.5) qualify only with adaptive thinking: Anthropic
|
|
35
|
+
* rejects a differing per-message effort with HTTP 400 on Sonnet 5.5
|
|
36
|
+
* `between_tools`, and asks callers to use adaptive thinking to vary effort.
|
|
34
37
|
*/
|
|
35
38
|
export declare function supportsPerMessageEffort(body: Record<string, unknown>): boolean;
|
|
36
39
|
/**
|
|
37
40
|
* The effort Anthropic applies when a request sets no `output_config.effort`:
|
|
38
|
-
* `medium` on Opus 5.5 and Haiku 5.5,
|
|
41
|
+
* the capability row's default (`medium` on Opus 5.5 and Haiku 5.5), and
|
|
42
|
+
* `high` on models without a row.
|
|
39
43
|
* A history entry without a recognized effort level uses this value.
|
|
40
44
|
*/
|
|
41
45
|
export declare function defaultAdaptiveEffort(model: unknown): AdaptiveEffort;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { AdaptiveEffort } from './mid-conversation-output-config.ts';
|
|
2
|
+
/**
|
|
3
|
+
* One row per Claude model that this plugin treats differently from an
|
|
4
|
+
* unknown model. Every per-model decision in Core (family checks, effort
|
|
5
|
+
* handling, Claude Code betas, turn-end notes, thinking-binding controls) and
|
|
6
|
+
* the per-model facts OpenCode and Pi read (catalogue entries, fallback
|
|
7
|
+
* eligibility) come from this table, so adding a model is one new row.
|
|
8
|
+
*
|
|
9
|
+
* Ids stay exact. A request model resolves to a row only when it equals the
|
|
10
|
+
* row's id (after removing OpenCode's `[1m]` context-window qualifier) or
|
|
11
|
+
* extends it as the row's `idSuffixes` allows; when several rows match, the
|
|
12
|
+
* longest id wins. A model that matches no row gets the defaults described on
|
|
13
|
+
* each field.
|
|
14
|
+
*/
|
|
15
|
+
/** Per-turn control beta Claude Code sends on the models whose rows list it. */
|
|
16
|
+
export declare const PER_TURN_CONTROL_BETA = "per-turn-control-2026-07-01";
|
|
17
|
+
/** Beta that allows turn-scoped system messages (`clear_at`). */
|
|
18
|
+
export declare const TURN_END_NOTE_BETA = "mid-conversation-system-clear-at-2026-08-21";
|
|
19
|
+
export declare const CLAUDE_CODE_FULL_AGENT_BETAS: readonly ["claude-code-20250219", 'oauth-2025-04-20', 'interleaved-thinking-2025-05-14', 'thinking-token-count-2026-05-13', 'context-management-2025-06-27', "prompt-caching-scope-2026-01-05", 'mid-conversation-tool-changes-2026-07-01', 'advanced-tool-use-2025-11-20', "mid-conversation-system-clear-at-2026-08-21", 'effort-2025-11-24', 'thinking-binding-controls-2026-08-01', 'thinking-display-updates-2026-08-18', 'extended-cache-ttl-2025-04-11', 'cache-diagnosis-2026-04-07'];
|
|
20
|
+
/**
|
|
21
|
+
* Claude Code's `anthropic-beta` list for each request class, before the
|
|
22
|
+
* body-dependent additions (turn-end note, structured outputs, fast mode and
|
|
23
|
+
* caller-supplied betas). `main` is a conversation turn; `title` is any other
|
|
24
|
+
* auxiliary request; `quota` is a one-token auxiliary probe.
|
|
25
|
+
*/
|
|
26
|
+
export type ClaudeCodeBetaLists = {
|
|
27
|
+
main: readonly string[];
|
|
28
|
+
title: readonly string[];
|
|
29
|
+
quota: readonly string[];
|
|
30
|
+
};
|
|
31
|
+
/** The lists for a model without its own row. */
|
|
32
|
+
export declare const CLAUDE_CODE_DEFAULT_BETAS: ClaudeCodeBetaLists;
|
|
33
|
+
export type ClaudeModelFamily = 'fable' | 'mythos' | 'opus' | 'sonnet' | 'haiku';
|
|
34
|
+
/** Per-million-token USD prices. */
|
|
35
|
+
export type ClaudeModelPricing = {
|
|
36
|
+
input: number;
|
|
37
|
+
output: number;
|
|
38
|
+
cacheRead: number;
|
|
39
|
+
cacheWrite5m: number;
|
|
40
|
+
cacheWrite1h: number;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Catalogue facts for a model the plugin registers itself in OpenCode and Pi,
|
|
44
|
+
* rather than taking from the host's own model list.
|
|
45
|
+
*/
|
|
46
|
+
export type ClaudeModelCatalogue = {
|
|
47
|
+
releaseDate: string;
|
|
48
|
+
contextWindow: number;
|
|
49
|
+
maxOutputTokens: number;
|
|
50
|
+
pricing: ClaudeModelPricing;
|
|
51
|
+
/** Higher prices for every token of a request above `inputTokensAbove` input tokens. */
|
|
52
|
+
longContext?: {
|
|
53
|
+
inputTokensAbove: number;
|
|
54
|
+
pricing: ClaudeModelPricing;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/** Source-model keys for content-filter recovery to Opus 4.8 in OpenCode. */
|
|
58
|
+
export type ClaudeRefusalRecoveryFamily = 'fable-5' | 'fable-5-1' | 'opus-5' | 'opus-5-5';
|
|
59
|
+
export type ClaudeModelCapabilities = {
|
|
60
|
+
/** Exact Anthropic model id. */
|
|
61
|
+
id: string;
|
|
62
|
+
/** Display name in host model pickers. */
|
|
63
|
+
name: string;
|
|
64
|
+
family: ClaudeModelFamily;
|
|
65
|
+
/**
|
|
66
|
+
* Longer ids that also resolve to this row: `any` accepts the id followed by
|
|
67
|
+
* `-` and anything (a date, `-fast`); `dated` accepts only `-YYYYMMDD`.
|
|
68
|
+
*/
|
|
69
|
+
idSuffixes: 'any' | 'dated';
|
|
70
|
+
/** Shown as limited availability. */
|
|
71
|
+
limited?: true;
|
|
72
|
+
/** Absent when the model comes from the host's own catalogue. */
|
|
73
|
+
catalogue?: ClaudeModelCatalogue;
|
|
74
|
+
/**
|
|
75
|
+
* Thinking settings the API accepts. OpenCode's transform.ts and Pi's
|
|
76
|
+
* convert.ts still normalize thinking with per-family code; a test checks
|
|
77
|
+
* that OpenCode's result agrees with this list.
|
|
78
|
+
*/
|
|
79
|
+
thinkingModes: readonly ('adaptive' | 'disabled' | 'between_tools')[];
|
|
80
|
+
/** The API rejects `tool_choice` of type `any` or `tool`, so it is removed. */
|
|
81
|
+
rejectsForcedToolChoice: boolean;
|
|
82
|
+
efforts: {
|
|
83
|
+
/**
|
|
84
|
+
* Efforts offered as host model variants with adaptive thinking. Absent:
|
|
85
|
+
* the host's own variants are left alone. Unknown models: absent.
|
|
86
|
+
*/
|
|
87
|
+
variants?: readonly AdaptiveEffort[];
|
|
88
|
+
/** Anthropic's effort when a request sets none. Unknown models: `high`. */
|
|
89
|
+
default: AdaptiveEffort;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* When effort changes may be sent as empty `role: "system"` messages:
|
|
93
|
+
* `always` (and top-level effort is then pinned on every request),
|
|
94
|
+
* `with-adaptive-thinking` (only when the request's thinking is adaptive),
|
|
95
|
+
* or `none`. Unknown models: `none`.
|
|
96
|
+
*/
|
|
97
|
+
effortMarkers: 'none' | 'with-adaptive-thinking' | 'always';
|
|
98
|
+
/** Turn-end notes may be inserted. Unknown models: no. */
|
|
99
|
+
turnEndNote: boolean;
|
|
100
|
+
/** `thinking.block_binding` may be set. Unknown models: no. */
|
|
101
|
+
thinkingBindingControls: boolean;
|
|
102
|
+
/** Unknown models: `CLAUDE_CODE_DEFAULT_BETAS`. */
|
|
103
|
+
claudeCodeBetas: ClaudeCodeBetaLists;
|
|
104
|
+
/** OpenCode may ask Anthropic for its server-side safety fallback. */
|
|
105
|
+
serverSideFallback: boolean;
|
|
106
|
+
/** OpenCode recovers from a content-filter refusal on Opus 4.8 under this key. */
|
|
107
|
+
refusalRecoveryFamily?: ClaudeRefusalRecoveryFamily;
|
|
108
|
+
/**
|
|
109
|
+
* Model-scoped weekly quota this model draws from. Quota matching in
|
|
110
|
+
* accounts.ts and native-quota-codec.ts still matches the substrings
|
|
111
|
+
* `fable`/`mythos`; a test checks that they agree with this field.
|
|
112
|
+
*/
|
|
113
|
+
scopedQuota?: 'fable' | 'mythos';
|
|
114
|
+
/**
|
|
115
|
+
* Fast mode (`speed: "fast"`) is offered. `isFastModeSupportedModel` also
|
|
116
|
+
* keeps its older prefix rule for ids outside this table.
|
|
117
|
+
*/
|
|
118
|
+
fastMode: boolean;
|
|
119
|
+
};
|
|
120
|
+
export declare const CLAUDE_MODEL_CAPABILITIES: readonly ClaudeModelCapabilities[];
|
|
121
|
+
/** Remove OpenCode's context-window qualifier before model-family checks. */
|
|
122
|
+
export declare function normalizeAnthropicModelId(model: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* The row for a request model, or `undefined` for a model this plugin does
|
|
125
|
+
* not special-case. See the table's description for how ids match.
|
|
126
|
+
*/
|
|
127
|
+
export declare function resolveClaudeModelCapabilities(model: unknown): ClaudeModelCapabilities | undefined;
|
|
128
|
+
/** The row for an exact model id; throws when the table has no such row. */
|
|
129
|
+
export declare function getClaudeModelCapabilities(id: string): ClaudeModelCapabilities;
|
|
130
|
+
/** Catalogue facts for an exact model id; throws when the row has none. */
|
|
131
|
+
export declare function getClaudeModelCatalogue(id: string): ClaudeModelCatalogue;
|
|
132
|
+
/**
|
|
133
|
+
* Whether effort is pinned in top-level `output_config` on every request,
|
|
134
|
+
* even one without an effort change.
|
|
135
|
+
*/
|
|
136
|
+
export declare function pinsEffortOnEveryRequest(model: unknown): boolean;
|