@cortexkit/anthropic-auth-core 2.2.3 → 2.2.5
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/index.d.ts +1 -1
- package/dist/index.js +85 -11
- package/dist/internal-types/claustrum/consumer.d.ts +7 -1
- package/dist/internal-types/claustrum/errors.d.ts +1 -1
- package/dist/internal-types/claustrum/index.d.ts +1 -1
- package/dist/internal-types/claustrum/roster.d.ts +31 -0
- package/dist/internal-types/commands/builtins.d.ts +37 -0
- package/dist/internal-types/commands/index.d.ts +1 -1
- package/dist/internal-types/setup/enroll.d.ts +1 -1
- package/dist/native-custody.d.ts +1 -1
- package/dist/pool-authority.d.ts +16 -1
- package/dist/sticky-routing.d.ts +2 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ export * from './oauth-profile.ts';
|
|
|
66
66
|
export { createWindowsOwnerOnly, ensureWindowsOwnerOnlyDirectory, isOwnerOnly, type OwnerOnlyOptions, } from './owner-only.ts';
|
|
67
67
|
export * from './pkce.ts';
|
|
68
68
|
export type { NativeEmptyInitJournal, NativeLegacyMigrationJournal, NativeMigrationJournal, } from './pool-authority.ts';
|
|
69
|
-
export { nativeMigrationAuthorityPhase, readNativeMigrationJournal, } from './pool-authority.ts';
|
|
69
|
+
export { nativeJournalMayAdoptLaterHostLogin, nativeMigrationAuthorityPhase, readNativeMigrationJournal, } from './pool-authority.ts';
|
|
70
70
|
export type { NativeLocalPoolBinding } from './pool-binding.ts';
|
|
71
71
|
export { captureNativeLocalPoolBinding } from './pool-binding.ts';
|
|
72
72
|
export * from './pool-paths.ts';
|
package/dist/index.js
CHANGED
|
@@ -2730,7 +2730,7 @@ async function assertHostsStopped(fence, env) {
|
|
|
2730
2730
|
|
|
2731
2731
|
// ../../node_modules/@cortexkit/common-auth/dist/setup/enroll.js
|
|
2732
2732
|
var ENROLLMENT_INCOMPLETE_MESSAGE = "Claustrum enrollment did not complete. Inspect and approve with ck, then rerun setup.";
|
|
2733
|
-
var UNSUPPORTED_VAULT_MESSAGE =
|
|
2733
|
+
var UNSUPPORTED_VAULT_MESSAGE = 'This Claustrum vault is too old to connect plugins. Run ck upgrade to move to Claustrum v0.2.0 or newer (read "Upgrading from v0.1.3" in its release notes first), or run setup without --claustrum to use local accounts.';
|
|
2734
2734
|
var ENROLLMENT_WAIT_MS = 300000;
|
|
2735
2735
|
var APPROVAL_POLL_MS = 1000;
|
|
2736
2736
|
var PROPOSE_BACKOFF_MS = [1000, 2000, 4000, 8000, 16000, 30000];
|
|
@@ -9558,7 +9558,7 @@ function formatEnrollmentStatus(status, scopedServing = false) {
|
|
|
9558
9558
|
return ["- Enrollment: setup is busy"];
|
|
9559
9559
|
case "unavailable":
|
|
9560
9560
|
return [
|
|
9561
|
-
|
|
9561
|
+
'- Enrollment: this Claustrum vault is too old to connect plugins. Run `ck upgrade` to move to Claustrum v0.2.0 or newer (read "Upgrading from v0.1.3" in its release notes first).'
|
|
9562
9562
|
];
|
|
9563
9563
|
case "pending":
|
|
9564
9564
|
return status.requestId && /^[A-Za-z0-9_-]{1,128}$/.test(status.requestId) ? [`- Enrollment: pending approval (${status.requestId})`, setup] : [
|
|
@@ -18408,6 +18408,52 @@ function acceptVaultRoute(path2, routeId) {
|
|
|
18408
18408
|
};
|
|
18409
18409
|
});
|
|
18410
18410
|
}
|
|
18411
|
+
function invalidOrder(message) {
|
|
18412
|
+
return new ClaustrumConsumerError("invalid-order", message);
|
|
18413
|
+
}
|
|
18414
|
+
function vaultOrderProblem(rows, routeIds) {
|
|
18415
|
+
if (!Array.isArray(routeIds))
|
|
18416
|
+
return "route ids must be an array of route ids";
|
|
18417
|
+
const rosterIds = new Set(rows.map((row) => row.routeId));
|
|
18418
|
+
const given = new Set;
|
|
18419
|
+
for (const id2 of routeIds) {
|
|
18420
|
+
if (typeof id2 !== "string")
|
|
18421
|
+
return "route ids must be an array of route ids";
|
|
18422
|
+
if (given.has(id2))
|
|
18423
|
+
return `route id ${id2} appears more than once`;
|
|
18424
|
+
if (!rosterIds.has(id2))
|
|
18425
|
+
return `route id ${id2} is not in the roster`;
|
|
18426
|
+
given.add(id2);
|
|
18427
|
+
}
|
|
18428
|
+
const missing2 = [...rosterIds].filter((id2) => !given.has(id2)).length;
|
|
18429
|
+
if (missing2 > 0)
|
|
18430
|
+
return `the order leaves out ${missing2} roster route id${missing2 === 1 ? "" : "s"}`;
|
|
18431
|
+
return;
|
|
18432
|
+
}
|
|
18433
|
+
function reorderVaultRoster(path2, routeIds, options = {}) {
|
|
18434
|
+
return mutateVaultRoster(path2, (current) => {
|
|
18435
|
+
const rows = current?.rows ?? [];
|
|
18436
|
+
const problem = vaultOrderProblem(rows, routeIds);
|
|
18437
|
+
if (problem)
|
|
18438
|
+
throw invalidOrder(problem);
|
|
18439
|
+
const byId = new Map;
|
|
18440
|
+
for (const row of rows) {
|
|
18441
|
+
const group = byId.get(row.routeId);
|
|
18442
|
+
if (group)
|
|
18443
|
+
group.push(row);
|
|
18444
|
+
else
|
|
18445
|
+
byId.set(row.routeId, [row]);
|
|
18446
|
+
}
|
|
18447
|
+
const ids = [...routeIds];
|
|
18448
|
+
const next = ids.flatMap((id2) => byId.get(id2) ?? []);
|
|
18449
|
+
if (!current || next.every((row, index) => row === rows[index]))
|
|
18450
|
+
return { result: { ids, outcome: "unchanged" } };
|
|
18451
|
+
return {
|
|
18452
|
+
next: { ...current, rows: next },
|
|
18453
|
+
result: { ids, outcome: "reordered" }
|
|
18454
|
+
};
|
|
18455
|
+
}, { ...options.signal && { signal: options.signal } });
|
|
18456
|
+
}
|
|
18411
18457
|
function receiptFence(row, receipt) {
|
|
18412
18458
|
if (!memberIds(row).includes(receipt.credentialId))
|
|
18413
18459
|
return "refuse";
|
|
@@ -19087,7 +19133,11 @@ class ClaustrumConsumer {
|
|
|
19087
19133
|
let current;
|
|
19088
19134
|
try {
|
|
19089
19135
|
current = await this.authorize(routeId, signal);
|
|
19090
|
-
|
|
19136
|
+
signal?.throwIfAborted();
|
|
19137
|
+
} catch (error) {
|
|
19138
|
+
if (signal?.aborted)
|
|
19139
|
+
throw error;
|
|
19140
|
+
}
|
|
19091
19141
|
if (decideScopedRetryAfter401(options.site, served, current, this.#logger)) {
|
|
19092
19142
|
await response.body?.cancel().catch(() => {});
|
|
19093
19143
|
served = current;
|
|
@@ -19114,6 +19164,12 @@ class ClaustrumConsumer {
|
|
|
19114
19164
|
await acceptVaultRoute(this.#options.rosterPath, routeId);
|
|
19115
19165
|
this.#roster = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
19116
19166
|
}
|
|
19167
|
+
async reorder(routeIds) {
|
|
19168
|
+
this.#assertOpen();
|
|
19169
|
+
const result = await reorderVaultRoster(this.#options.rosterPath, routeIds);
|
|
19170
|
+
this.#roster = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
19171
|
+
return result;
|
|
19172
|
+
}
|
|
19117
19173
|
async recordQuota(routeId, observation, attempt) {
|
|
19118
19174
|
this.#assertOpen();
|
|
19119
19175
|
return recordVaultQuota(this.#options.rosterPath, {
|
|
@@ -19187,6 +19243,7 @@ function nativeCode(value) {
|
|
|
19187
19243
|
case "host-slot-login":
|
|
19188
19244
|
case "host-slot-placeholder":
|
|
19189
19245
|
case "placeholder-refresh":
|
|
19246
|
+
case "invalid-order":
|
|
19190
19247
|
return value;
|
|
19191
19248
|
default:
|
|
19192
19249
|
return "unavailable";
|
|
@@ -20908,6 +20965,9 @@ function nativeMigrationAuthorityPhase(journal) {
|
|
|
20908
20965
|
return;
|
|
20909
20966
|
return journal.phase;
|
|
20910
20967
|
}
|
|
20968
|
+
function nativeJournalMayAdoptLaterHostLogin(journal, host) {
|
|
20969
|
+
return host === "opencode" && journal !== undefined && journal.kind !== "empty-init" && journal.host === "opencode" && journal.phase === "retired" && journal.activation === null;
|
|
20970
|
+
}
|
|
20911
20971
|
async function requireNativePoolAuthority(paths) {
|
|
20912
20972
|
const journal = await readNativeMigrationJournal(paths);
|
|
20913
20973
|
if (!journal)
|
|
@@ -20947,7 +21007,7 @@ async function writeJournal(paths, journal, assertOwned, hooks) {
|
|
|
20947
21007
|
});
|
|
20948
21008
|
await hooks.onWriteStep?.("after-write", snapshot);
|
|
20949
21009
|
}
|
|
20950
|
-
async function beginNativeMigration(paths, input, hooks = {}) {
|
|
21010
|
+
async function beginNativeMigration(paths, input, hooks = {}, replaces) {
|
|
20951
21011
|
try {
|
|
20952
21012
|
requireNativeMigrationDataObject(input);
|
|
20953
21013
|
} catch {
|
|
@@ -20980,6 +21040,12 @@ async function beginNativeMigration(paths, input, hooks = {}) {
|
|
|
20980
21040
|
renew: true
|
|
20981
21041
|
}, async (lock) => {
|
|
20982
21042
|
const current = await readNativeMigrationJournal(paths);
|
|
21043
|
+
if (replaces) {
|
|
21044
|
+
if (initial.version !== 5 || !nativeJournalMayAdoptLaterHostLogin(replaces, initial.host) || !current || nativeMigrationCanonicalJson(current) !== nativeMigrationCanonicalJson(replaces))
|
|
21045
|
+
throw new NativeAuthorityError("journal-conflict");
|
|
21046
|
+
await writeJournal(paths, initial, () => lock.assertOwned(), hooks);
|
|
21047
|
+
return initial;
|
|
21048
|
+
}
|
|
20983
21049
|
if (current?.kind === "empty-init") {
|
|
20984
21050
|
if (current.host !== initial.host)
|
|
20985
21051
|
throw new NativeAuthorityError("journal-conflict");
|
|
@@ -21355,6 +21421,7 @@ var codes = new Set([
|
|
|
21355
21421
|
"host-slot-login",
|
|
21356
21422
|
"host-slot-placeholder",
|
|
21357
21423
|
"placeholder-refresh",
|
|
21424
|
+
"invalid-order",
|
|
21358
21425
|
"publication-refused",
|
|
21359
21426
|
"unsafe-runtime",
|
|
21360
21427
|
"invalid-runtime",
|
|
@@ -24496,7 +24563,7 @@ class StickySessionRouter {
|
|
|
24496
24563
|
}) > 0) : undefined;
|
|
24497
24564
|
const selected = preferred ?? this.selectCandidate({ ...input, candidates, state });
|
|
24498
24565
|
if (!selected) {
|
|
24499
|
-
if (current) {
|
|
24566
|
+
if (current && !input.preserveOnNoCandidate) {
|
|
24500
24567
|
delete state.assignments[key];
|
|
24501
24568
|
save("delete");
|
|
24502
24569
|
}
|
|
@@ -27511,7 +27578,7 @@ async function capture2(input, checkPool = false) {
|
|
|
27511
27578
|
refuse3();
|
|
27512
27579
|
const current = await readNativeMigrationJournal(input.paths);
|
|
27513
27580
|
const emptyInit = current?.kind === "empty-init";
|
|
27514
|
-
|
|
27581
|
+
let journal = current?.kind === "empty-init" ? undefined : current;
|
|
27515
27582
|
if (emptyInit) {
|
|
27516
27583
|
if (current.host !== input.host || input.routingDestinationPath !== resolveLocalRoutingDestination(input.host, input.paths, input.env))
|
|
27517
27584
|
refuse3();
|
|
@@ -27541,6 +27608,11 @@ async function capture2(input, checkPool = false) {
|
|
|
27541
27608
|
refuse3();
|
|
27542
27609
|
if (journal && (journal.host !== input.host || journal.hostAuthPath !== hostAuthPath || journal.routingPaths.source !== routingSourcePath || journal.routingPaths.destination !== routingDestinationPath))
|
|
27543
27610
|
refuse3();
|
|
27611
|
+
let replaces;
|
|
27612
|
+
if (nativeJournalMayAdoptLaterHostLogin(journal, input.host) && entry2.kind === "oauth" && !await nativePoolHoldsAccountData({ paths: input.paths })) {
|
|
27613
|
+
replaces = journal;
|
|
27614
|
+
journal = undefined;
|
|
27615
|
+
}
|
|
27544
27616
|
if (journal?.phase === "committed" || journal?.phase === "retired") {
|
|
27545
27617
|
const missing2 = (role, path2) => ({
|
|
27546
27618
|
role,
|
|
@@ -27575,7 +27647,7 @@ async function capture2(input, checkPool = false) {
|
|
|
27575
27647
|
const config = await readNativeMigrationSource("config", input.legacyConfigPath ?? input.paths.legacyConfig);
|
|
27576
27648
|
const state = await readNativeMigrationSource("state", input.legacyStatePath ?? input.paths.legacyState);
|
|
27577
27649
|
const routing = await readNativeMigrationSource("routing", input.routingSourcePath);
|
|
27578
|
-
const routingDestination = emptyInit || journal?.kind === "legacy-import" ? await readNativeMigrationSource("routing", input.routingDestinationPath) : undefined;
|
|
27650
|
+
const routingDestination = emptyInit || replaces || journal?.kind === "legacy-import" ? await readNativeMigrationSource("routing", input.routingDestinationPath) : undefined;
|
|
27579
27651
|
if (routingDestination)
|
|
27580
27652
|
owned(routingDestination);
|
|
27581
27653
|
for (const source2 of [config, state, routing])
|
|
@@ -27634,6 +27706,7 @@ async function capture2(input, checkPool = false) {
|
|
|
27634
27706
|
routing,
|
|
27635
27707
|
auth,
|
|
27636
27708
|
journal: current,
|
|
27709
|
+
...replaces ? { replaces } : {},
|
|
27637
27710
|
routingDestination,
|
|
27638
27711
|
projection,
|
|
27639
27712
|
seedInput,
|
|
@@ -27838,11 +27911,11 @@ async function runNativeMigration(input, hooks = {}) {
|
|
|
27838
27911
|
const captured = await capture2(operation, true);
|
|
27839
27912
|
if (operation.preflight) {
|
|
27840
27913
|
const previous = preflights.get(operation.preflight);
|
|
27841
|
-
if (!previous || operation.preflight.storageId !== paths.storageId || operation.preflight.host !== operation.host || previous.config.digest !== captured.config.digest || previous.state.digest !== captured.state.digest || previous.routing.digest !== captured.routing.digest || previous.routingDestination?.digest !== captured.routingDestination?.digest || inspectNativeHostAuthEntry(operation.host, previous.auth.data).digest !== inspectNativeHostAuthEntry(operation.host, captured.auth.data).digest || previous.hostAuthPath !== captured.hostAuthPath || previous.routingSourcePath !== captured.routingSourcePath || previous.routingDestinationPath !== captured.routingDestinationPath)
|
|
27914
|
+
if (!previous || operation.preflight.storageId !== paths.storageId || operation.preflight.host !== operation.host || previous.config.digest !== captured.config.digest || previous.state.digest !== captured.state.digest || previous.routing.digest !== captured.routing.digest || previous.routingDestination?.digest !== captured.routingDestination?.digest || inspectNativeHostAuthEntry(operation.host, previous.auth.data).digest !== inspectNativeHostAuthEntry(operation.host, captured.auth.data).digest || previous.hostAuthPath !== captured.hostAuthPath || previous.routingSourcePath !== captured.routingSourcePath || previous.routingDestinationPath !== captured.routingDestinationPath || previous.replaces === undefined !== (captured.replaces === undefined))
|
|
27842
27915
|
refuse3();
|
|
27843
27916
|
}
|
|
27844
|
-
const emptyInit = captured.journal?.kind === "empty-init";
|
|
27845
|
-
let journal = captured.journal?.kind === "empty-init" ? undefined : captured.journal;
|
|
27917
|
+
const emptyInit = captured.journal?.kind === "empty-init" || captured.replaces !== undefined;
|
|
27918
|
+
let journal = captured.journal?.kind === "empty-init" || captured.replaces ? undefined : captured.journal;
|
|
27846
27919
|
const store = createNativePoolStore({
|
|
27847
27920
|
paths,
|
|
27848
27921
|
quota: nativeQuotaCodec,
|
|
@@ -27910,7 +27983,7 @@ async function runNativeMigration(input, hooks = {}) {
|
|
|
27910
27983
|
destination: captured.routingDestinationPath
|
|
27911
27984
|
},
|
|
27912
27985
|
...operation.requestVaultActivation ? { activation: "requested" } : {}
|
|
27913
|
-
}, journalHooks);
|
|
27986
|
+
}, journalHooks, captured.replaces);
|
|
27914
27987
|
}
|
|
27915
27988
|
let bytes;
|
|
27916
27989
|
let seed;
|
|
@@ -32916,6 +32989,7 @@ export {
|
|
|
32916
32989
|
nativeMigrationAuthorityPhase,
|
|
32917
32990
|
nativeLocalQuotaLineage,
|
|
32918
32991
|
nativeLocalCredentialValidationMatches,
|
|
32992
|
+
nativeJournalMayAdoptLaterHostLogin,
|
|
32919
32993
|
nativeCacheKeepAlways,
|
|
32920
32994
|
nativeAccountPolicy,
|
|
32921
32995
|
nativeAccountCanServe,
|
|
@@ -4,7 +4,7 @@ import type { RoutingRow } from '../routing/index.js';
|
|
|
4
4
|
import { type ClaustrumFamily, type ClaustrumScopedAttempt, type ClaustrumScopedClient, type IdentityParser, type KeptReceiptState, type VaultGrantReach } from './custody.js';
|
|
5
5
|
import { type ClaustrumLogger } from './errors.js';
|
|
6
6
|
import { type InsulaQuotaOptions, type InsulaQuotaResult } from './insula.js';
|
|
7
|
-
import { type AccountMapper, type QuotaReceipt, type VaultRosterFile } from './roster.js';
|
|
7
|
+
import { type AccountMapper, type QuotaReceipt, type ReorderVaultRosterResult, type VaultRosterFile } from './roster.js';
|
|
8
8
|
import { type WatchMode } from './watch.js';
|
|
9
9
|
export interface ClaustrumConsumerOptions<Q = QuotaObservation> {
|
|
10
10
|
/**
|
|
@@ -157,6 +157,12 @@ export declare class ClaustrumConsumer<Q = QuotaObservation> {
|
|
|
157
157
|
/** Decline a vault account: it stays listed and never routes until accepted. */
|
|
158
158
|
decline(routeId: string): Promise<void>;
|
|
159
159
|
accept(routeId: string): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* Set the order vault accounts are tried in (`reorderVaultRoster`), then
|
|
162
|
+
* re-read the roster, so the next routing decision in this process uses
|
|
163
|
+
* the new order without waiting for a discovery. Never contacts the vault.
|
|
164
|
+
*/
|
|
165
|
+
reorder(routeIds: readonly string[]): Promise<ReorderVaultRosterResult>;
|
|
160
166
|
/**
|
|
161
167
|
* Store a quota or profile observation for a vault route. The receipt the
|
|
162
168
|
* reading was taken with is required: the observation lands only while the
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `code`, a `class` and an `action`), so callers can tell the vault's verdict
|
|
5
5
|
* apart from a check made on this side.
|
|
6
6
|
*/
|
|
7
|
-
export type ClaustrumConsumerFailureKind = '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';
|
|
7
|
+
export type ClaustrumConsumerFailureKind = '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' | 'invalid-order';
|
|
8
8
|
export declare class ClaustrumConsumerError extends Error {
|
|
9
9
|
readonly kind: ClaustrumConsumerFailureKind;
|
|
10
10
|
constructor(kind: ClaustrumConsumerFailureKind, message: string);
|
|
@@ -10,7 +10,7 @@ export { assertHostSlotMatchesMode, assertNotCustodyPlaceholder, CUSTODY_PLACEHO
|
|
|
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
12
|
export { drainVaultQuota } from './quota-writer.js';
|
|
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
|
+
export { type AccountMapper, acceptVaultRoute, DEFAULT_ROUTE_PREFIX, declineVaultRoute, type MutateVaultRosterOptions, mutateVaultRoster, type ProjectionOptions, projectVaultRoster, type QuotaReceipt, type ReorderVaultRosterOptions, type ReorderVaultRosterResult, readVaultRoster, recordVaultAccountQuota, recordVaultQuota, refreshVaultRoster, reorderVaultRoster, resolveVaultPrimary, type VaultPrimary, type VaultPrimaryBinding, type VaultPrimaryUnavailableReason, type VaultRosterFile, type VaultRosterLockContext, type VaultRosterRow, vaultRoutingRows, } from './roster.js';
|
|
14
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';
|
|
15
15
|
/**
|
|
16
16
|
* Connect the client that lists and fetches this consumer's vault credentials
|
|
@@ -119,6 +119,37 @@ export declare function mutateVaultRoster<T>(path: string, change: (current: Vau
|
|
|
119
119
|
export declare function declineVaultRoute(path: string, routeId: string): Promise<undefined>;
|
|
120
120
|
/** Lift the user's decline for a vault account and every alias of it. */
|
|
121
121
|
export declare function acceptVaultRoute(path: string, routeId: string): Promise<undefined>;
|
|
122
|
+
/** Options of `reorderVaultRoster`. */
|
|
123
|
+
export interface ReorderVaultRosterOptions {
|
|
124
|
+
/** Aborts the wait for the roster's write lock. */
|
|
125
|
+
signal?: AbortSignal;
|
|
126
|
+
}
|
|
127
|
+
export interface ReorderVaultRosterResult {
|
|
128
|
+
/** The route id order now on disk. */
|
|
129
|
+
ids: string[];
|
|
130
|
+
/** `unchanged` when the roster was already in this order; nothing was written. */
|
|
131
|
+
outcome: 'reordered' | 'unchanged';
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Set the order vault accounts are tried in. Routing reads that order from
|
|
135
|
+
* the roster's row order (`vaultRoutingRows`), and a later discovery keeps
|
|
136
|
+
* each account at its position, so the order lasts until the next reorder.
|
|
137
|
+
* The order is this host's routing preference: the vault has no order of its
|
|
138
|
+
* own, and this never contacts it.
|
|
139
|
+
*
|
|
140
|
+
* `routeIds` must name every roster route id exactly once; anything else
|
|
141
|
+
* (an unknown, missing or repeated id) refuses with `invalid-order` and
|
|
142
|
+
* writes nothing. It runs under the roster's write lock, like every other
|
|
143
|
+
* roster write, so a quota reading or decline committed meanwhile is kept.
|
|
144
|
+
* Each row is kept as the same object, so only the positions change: every
|
|
145
|
+
* row's fields and the rest of the file stay as they were. An order equal to
|
|
146
|
+
* the current one writes nothing. A host with no roster file yet has no
|
|
147
|
+
* routes, so only the empty order is accepted.
|
|
148
|
+
*
|
|
149
|
+
* A `ClaustrumConsumer` in the same process does not see the new order until
|
|
150
|
+
* it re-reads the file: call `consumer.reorder` instead to update both.
|
|
151
|
+
*/
|
|
152
|
+
export declare function reorderVaultRoster(path: string, routeIds: readonly string[], options?: ReorderVaultRosterOptions): Promise<ReorderVaultRosterResult>;
|
|
122
153
|
/**
|
|
123
154
|
* The receipt fields a quota or profile observation must carry to say which
|
|
124
155
|
* send (credential and account) it came from. Pass the
|
|
@@ -48,6 +48,43 @@ export interface RoutingSectionOptions {
|
|
|
48
48
|
*/
|
|
49
49
|
orderedVariants?: MenuChoice[];
|
|
50
50
|
formerMainId?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The vault accounts' routing order, for a plugin that can run in vault
|
|
53
|
+
* mode. Called on each build; return the order while the plugin routes
|
|
54
|
+
* through vault accounts and undefined otherwise. While it returns one, the
|
|
55
|
+
* section shows and sets the vault accounts' order (by the name the menu
|
|
56
|
+
* shows for each account) instead of the pool roster's. Wire it to
|
|
57
|
+
* `ClaustrumConsumer.snapshot()` and `ClaustrumConsumer.reorder`, or to
|
|
58
|
+
* `readVaultRoster` and `reorderVaultRoster` for a plugin without a
|
|
59
|
+
* consumer.
|
|
60
|
+
*/
|
|
61
|
+
vaultOrder?: () => VaultRoutingOrder | undefined | Promise<VaultRoutingOrder | undefined>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The order vault accounts are tried in, as the Routing section reads and
|
|
65
|
+
* sets it in vault mode. Shaped after `/claustrum`'s roster, without
|
|
66
|
+
* importing it, so the menu does not need the vault client.
|
|
67
|
+
*/
|
|
68
|
+
export interface VaultRoutingOrder {
|
|
69
|
+
/**
|
|
70
|
+
* Every vault roster row, in roster (routing) order: its route id and the
|
|
71
|
+
* name the plugin shows for that account (the roster row's `label`, or its
|
|
72
|
+
* email). Route ids are long and opaque, so the section shows and accepts
|
|
73
|
+
* labels; a route id is still accepted wherever a label is.
|
|
74
|
+
*/
|
|
75
|
+
rows: readonly {
|
|
76
|
+
id: string;
|
|
77
|
+
label: string;
|
|
78
|
+
}[];
|
|
79
|
+
/**
|
|
80
|
+
* Sets the order. `ids` are route ids, every one exactly once. Wire it to
|
|
81
|
+
* `ClaustrumConsumer.reorder` or `reorderVaultRoster`, which refuse any
|
|
82
|
+
* other list without writing.
|
|
83
|
+
*/
|
|
84
|
+
reorder(ids: readonly string[]): Promise<{
|
|
85
|
+
ids: readonly string[];
|
|
86
|
+
outcome: 'reordered' | 'unchanged';
|
|
87
|
+
}>;
|
|
51
88
|
}
|
|
52
89
|
export interface LimitsSectionOptions {
|
|
53
90
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { AccountsSectionOptions, LimitsSectionOptions, LoginOutcome, QuotaSectionOptions, RoutingSectionOptions, } from './builtins.js';
|
|
1
|
+
export type { AccountsSectionOptions, LimitsSectionOptions, LoginOutcome, QuotaSectionOptions, RoutingSectionOptions, VaultRoutingOrder, } from './builtins.js';
|
|
2
2
|
export { MENU_DISABLED_REASON } from './builtins.js';
|
|
3
3
|
export type { CommandMenu, CommandMenuOptions, StoreSectionSlot, } from './menu.js';
|
|
4
4
|
export { createCommandMenu, parseApplyRequest } from './menu.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type MenuTerminal } from '../auth-menu/terminal.js';
|
|
2
2
|
import type { SetupHost, SetupIO, SetupPlugin } from './types.js';
|
|
3
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
|
|
4
|
+
export declare const UNSUPPORTED_VAULT_MESSAGE = "This Claustrum vault is too old to connect plugins. Run ck upgrade to move to Claustrum v0.2.0 or newer (read \"Upgrading from v0.1.3\" in its release notes first), or run setup without --claustrum to use local accounts.";
|
|
5
5
|
/**
|
|
6
6
|
* The longest setup waits, in total, for the vault to create the enrollment
|
|
7
7
|
* request and for an operator to approve it. It matches the wait setup always
|
package/dist/native-custody.d.ts
CHANGED
|
@@ -203,7 +203,7 @@ export interface NativeCustodyInventory {
|
|
|
203
203
|
}[];
|
|
204
204
|
};
|
|
205
205
|
}
|
|
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';
|
|
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' | 'invalid-order';
|
|
207
207
|
export declare class NativeCustodyError extends Error {
|
|
208
208
|
readonly code: NativeCustodyErrorCode;
|
|
209
209
|
constructor(code: NativeCustodyErrorCode);
|
package/dist/pool-authority.d.ts
CHANGED
|
@@ -142,6 +142,16 @@ export declare function readNativeMigrationJournal(paths: NativePoolPaths, owner
|
|
|
142
142
|
* that admits requests from the journal uses this one predicate.
|
|
143
143
|
*/
|
|
144
144
|
export declare function nativeMigrationAuthorityPhase(journal: NativeMigrationJournal | undefined): 'committed' | 'retired' | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Whether a finished legacy import may be replaced by a fresh import of a
|
|
147
|
+
* later OpenCode login. A first OpenCode 1 setup with no login finishes a
|
|
148
|
+
* legacy import of nothing instead of recording empty-init (only OpenCode 2
|
|
149
|
+
* setup records empty-init). Such a journal stands in for empty-init only when
|
|
150
|
+
* it is retired with no requested or completed vault switch; callers must still
|
|
151
|
+
* prove the pool holds no account data, so a pool with accounts is never
|
|
152
|
+
* re-imported.
|
|
153
|
+
*/
|
|
154
|
+
export declare function nativeJournalMayAdoptLaterHostLogin(journal: NativeMigrationJournal | undefined, host: 'opencode' | 'pi'): journal is NativeLegacyMigrationJournal;
|
|
145
155
|
/** An empty or readable store is not proof that the offline authority flip completed. */
|
|
146
156
|
export declare function requireNativePoolAuthority(paths: NativePoolPaths): Promise<NativeMigrationJournal>;
|
|
147
157
|
interface JournalHooks {
|
|
@@ -154,7 +164,12 @@ interface JournalHooks {
|
|
|
154
164
|
onWriteStep?: (step: 'before-write' | 'after-write', journal: NativeMigrationJournal) => Promise<void>;
|
|
155
165
|
}
|
|
156
166
|
/** Migration resume retains the original digests and resolved paths so a retry cannot adopt changed inputs or redirect writes. */
|
|
157
|
-
export declare function beginNativeMigration(paths: NativePoolPaths, input: NativeMigrationInput, hooks?: JournalHooks
|
|
167
|
+
export declare function beginNativeMigration(paths: NativePoolPaths, input: NativeMigrationInput, hooks?: JournalHooks,
|
|
168
|
+
/**
|
|
169
|
+
* The retired journal a fresh v5 import replaces, as read by the caller.
|
|
170
|
+
* The write refuses unless the journal on disk still equals it exactly.
|
|
171
|
+
*/
|
|
172
|
+
replaces?: NativeLegacyMigrationJournal): Promise<NativeLegacyMigrationJournal>;
|
|
158
173
|
/** Save the expected host-auth entry and routing digests together before changing files, so recovery can recognize completed writes. */
|
|
159
174
|
export declare function recordNativeMigrationExpectations(paths: NativePoolPaths, expectations: NativeMigrationExpectations, hooks?: JournalHooks): Promise<NativeLegacyMigrationJournal>;
|
|
160
175
|
/**
|
package/dist/sticky-routing.d.ts
CHANGED
|
@@ -148,6 +148,8 @@ export declare class StickySessionRouter {
|
|
|
148
148
|
inputBytes: number;
|
|
149
149
|
preferredAccountId?: string;
|
|
150
150
|
excludeAccountIds?: ReadonlySet<string>;
|
|
151
|
+
/** Leave the current pin intact when selection cannot offer an account. */
|
|
152
|
+
preserveOnNoCandidate?: boolean;
|
|
151
153
|
}): Promise<StickyRouteResolution | null>;
|
|
152
154
|
clear(sessionId: string): Promise<void>;
|
|
153
155
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/anthropic-auth-core",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prepublishOnly": "bun run build"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@cortexkit/common-auth": "0.
|
|
33
|
+
"@cortexkit/common-auth": "0.25.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@cortexkit/claustrum-client": "0.12.0",
|