@cortexkit/anthropic-auth-core 2.4.9 → 2.4.11
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/holder-registry.d.ts +23 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.js +204 -52
- package/dist/layout-fence.d.ts +3 -2
- package/dist/request-abort.d.ts +16 -0
- package/package.json +1 -1
|
@@ -105,22 +105,34 @@ export interface HolderLiveness {
|
|
|
105
105
|
pidAlive(pid: number): boolean;
|
|
106
106
|
/** Undefined or null when it can't be read. */
|
|
107
107
|
incarnation(pid: number): Promise<string | null>;
|
|
108
|
+
/** Wall clock and OS uptime; tests replace both. */
|
|
109
|
+
now?(): number;
|
|
110
|
+
uptime?(): number;
|
|
108
111
|
}
|
|
109
112
|
/** The OS's fixed per-process value for `pid`, or null when none is read. */
|
|
110
113
|
export declare function processIncarnation(pid: number): Promise<string | null>;
|
|
111
114
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* So pid reuse can keep a stale entry, but never clears a live one.
|
|
115
|
+
* A process recorded before this boot cannot still be running, even if its
|
|
116
|
+
* pid is alive again. Keep a five-minute margin for clock imprecision, and
|
|
117
|
+
* keep blocking when the timestamp is missing, invalid or in the future.
|
|
116
118
|
*/
|
|
117
|
-
export declare function
|
|
119
|
+
export declare function recordPredatesBoot(startedAt: unknown, clock?: Pick<HolderLiveness, 'now' | 'uptime'>): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Whether an entry's process may still be running. An entry from before
|
|
122
|
+
* this boot or a dead pid is stale. Otherwise an unreadable incarnation
|
|
123
|
+
* counts as alive; only a different incarnation clears a live pid.
|
|
124
|
+
*/
|
|
125
|
+
export declare function holderEntryIsLive(entry: Pick<HolderEntry, 'pid' | 'incarnation'> & {
|
|
126
|
+
registeredAt?: unknown;
|
|
127
|
+
}, liveness?: HolderLiveness): Promise<boolean>;
|
|
118
128
|
export interface HolderFileContents {
|
|
119
129
|
/** Entries as found, including any this version doesn't understand. */
|
|
120
130
|
entries: unknown[];
|
|
121
131
|
}
|
|
122
|
-
/** An entry's pid and incarnation
|
|
123
|
-
export declare function holderEntryLiveness(value: unknown): Pick<HolderEntry, 'pid' | 'incarnation'>
|
|
132
|
+
/** An entry's liveness fields when its pid and incarnation have a usable shape. */
|
|
133
|
+
export declare function holderEntryLiveness(value: unknown): (Pick<HolderEntry, 'pid' | 'incarnation'> & {
|
|
134
|
+
registeredAt?: unknown;
|
|
135
|
+
}) | undefined;
|
|
124
136
|
/**
|
|
125
137
|
* Read a holder file. Undefined when it is absent. A file that exists but
|
|
126
138
|
* doesn't parse throws: rewriting it would erase other processes' entries.
|
|
@@ -185,10 +197,10 @@ export interface NativeHolderRegistration {
|
|
|
185
197
|
*/
|
|
186
198
|
export declare function ensureHolderDirectory(dir: string, ownerOnly?: OwnerOnlyOptions): Promise<void>;
|
|
187
199
|
/**
|
|
188
|
-
* Add `entry` to `holderFile`, pruning entries
|
|
189
|
-
*
|
|
190
|
-
* for this process, kind and files is already there. A holder
|
|
191
|
-
* doesn't parse throws and is never overwritten.
|
|
200
|
+
* Add `entry` to `holderFile`, pruning stale entries, while the caller holds
|
|
201
|
+
* that file's `holders` lock. Writes nothing when nothing was pruned and a
|
|
202
|
+
* live entry for this process, kind and files is already there. A holder
|
|
203
|
+
* file that doesn't parse throws and is never overwritten.
|
|
192
204
|
*/
|
|
193
205
|
export declare function publishHolderEntryLocked(holderFile: string, entry: HolderEntry, options: {
|
|
194
206
|
liveness?: HolderLiveness;
|
package/dist/index.d.ts
CHANGED
|
@@ -87,6 +87,7 @@ export * from './quota-manager.ts';
|
|
|
87
87
|
export * from './quotas.ts';
|
|
88
88
|
export * from './relay.ts';
|
|
89
89
|
export * from './relocation-guard.ts';
|
|
90
|
+
export * from './request-abort.ts';
|
|
90
91
|
export * from './request-gzip.ts';
|
|
91
92
|
export * from './request-history.ts';
|
|
92
93
|
export * from './routing.ts';
|
package/dist/index.js
CHANGED
|
@@ -4327,6 +4327,73 @@ async function generatePKCE() {
|
|
|
4327
4327
|
};
|
|
4328
4328
|
}
|
|
4329
4329
|
|
|
4330
|
+
// src/request-abort.ts
|
|
4331
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4332
|
+
function raceWithSignal(signal, operation) {
|
|
4333
|
+
if (!signal)
|
|
4334
|
+
return operation();
|
|
4335
|
+
if (signal.aborted)
|
|
4336
|
+
return Promise.reject(signal.reason);
|
|
4337
|
+
return new Promise((resolve5, reject) => {
|
|
4338
|
+
const aborted = () => reject(signal.reason);
|
|
4339
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
4340
|
+
const finish = () => signal.removeEventListener("abort", aborted);
|
|
4341
|
+
Promise.resolve().then(() => {
|
|
4342
|
+
signal.throwIfAborted();
|
|
4343
|
+
return operation();
|
|
4344
|
+
}).then((value) => {
|
|
4345
|
+
finish();
|
|
4346
|
+
if (signal.aborted)
|
|
4347
|
+
reject(signal.reason);
|
|
4348
|
+
else
|
|
4349
|
+
resolve5(value);
|
|
4350
|
+
}, (error) => {
|
|
4351
|
+
finish();
|
|
4352
|
+
reject(signal.aborted ? signal.reason : error);
|
|
4353
|
+
});
|
|
4354
|
+
});
|
|
4355
|
+
}
|
|
4356
|
+
function abortableFetch(send) {
|
|
4357
|
+
return (input, init) => {
|
|
4358
|
+
const signal = init?.signal !== undefined ? init.signal : input instanceof Request ? input.signal : undefined;
|
|
4359
|
+
return runWithRequestSignal(signal, () => send(input, init));
|
|
4360
|
+
};
|
|
4361
|
+
}
|
|
4362
|
+
function withAbortableFetch(options) {
|
|
4363
|
+
return { ...options, fetch: abortableFetch(options.fetch) };
|
|
4364
|
+
}
|
|
4365
|
+
var AUXILIARY_REQUEST_TIMEOUT_MS = 30000;
|
|
4366
|
+
function auxiliaryRequestSignal(signal) {
|
|
4367
|
+
const deadline = AbortSignal.timeout(AUXILIARY_REQUEST_TIMEOUT_MS);
|
|
4368
|
+
return signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
4369
|
+
}
|
|
4370
|
+
var requests = new AsyncLocalStorage;
|
|
4371
|
+
function requestSignal() {
|
|
4372
|
+
return requests.getStore()?.signal;
|
|
4373
|
+
}
|
|
4374
|
+
function commitRequestChange(commit) {
|
|
4375
|
+
const request = requests.getStore();
|
|
4376
|
+
request?.signal?.throwIfAborted();
|
|
4377
|
+
if (request)
|
|
4378
|
+
request.commits.push(commit);
|
|
4379
|
+
else
|
|
4380
|
+
commit();
|
|
4381
|
+
}
|
|
4382
|
+
function runWithRequestSignal(signal, operation) {
|
|
4383
|
+
const request = { signal, commits: [] };
|
|
4384
|
+
return raceWithSignal(signal, () => requests.run(request, async () => {
|
|
4385
|
+
try {
|
|
4386
|
+
const result = await operation();
|
|
4387
|
+
signal?.throwIfAborted();
|
|
4388
|
+
for (const commit of request.commits)
|
|
4389
|
+
commit();
|
|
4390
|
+
return result;
|
|
4391
|
+
} finally {
|
|
4392
|
+
request.commits.length = 0;
|
|
4393
|
+
}
|
|
4394
|
+
}));
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4330
4397
|
// src/auth.ts
|
|
4331
4398
|
function parseRetryAfterHeader(value) {
|
|
4332
4399
|
if (!value)
|
|
@@ -4370,7 +4437,9 @@ async function refreshClaudeOAuthToken(input) {
|
|
|
4370
4437
|
const delay3 = baseDelayMs * 2 ** (attempt - 1);
|
|
4371
4438
|
await new Promise((resolve5) => setTimeoutImpl(resolve5, delay3));
|
|
4372
4439
|
}
|
|
4373
|
-
const
|
|
4440
|
+
const signal = auxiliaryRequestSignal();
|
|
4441
|
+
const response = await raceWithSignal(signal, () => fetchImpl(TOKEN_URL, {
|
|
4442
|
+
signal,
|
|
4374
4443
|
method: "POST",
|
|
4375
4444
|
redirect: "error",
|
|
4376
4445
|
headers: {
|
|
@@ -4384,16 +4453,16 @@ async function refreshClaudeOAuthToken(input) {
|
|
|
4384
4453
|
client_id: CLIENT_ID,
|
|
4385
4454
|
scope: REFRESH_SCOPE
|
|
4386
4455
|
})
|
|
4387
|
-
});
|
|
4456
|
+
}));
|
|
4388
4457
|
if (!response.ok) {
|
|
4389
4458
|
if (response.status >= 500 && attempt < maxRetries) {
|
|
4390
|
-
await response.body?.cancel().catch(() => {});
|
|
4459
|
+
await raceWithSignal(signal, async () => response.body?.cancel()).catch(() => {});
|
|
4391
4460
|
continue;
|
|
4392
4461
|
}
|
|
4393
|
-
const body = await response.text().catch(() => "");
|
|
4462
|
+
const body = await raceWithSignal(signal, () => response.text()).catch(() => "");
|
|
4394
4463
|
throw new ClaudeOAuthRefreshError(response.status, body, response.headers.get("retry-after"));
|
|
4395
4464
|
}
|
|
4396
|
-
const json = await response.json();
|
|
4465
|
+
const json = await raceWithSignal(signal, () => response.json());
|
|
4397
4466
|
const refreshedAt = input.now?.() ?? Date.now();
|
|
4398
4467
|
return {
|
|
4399
4468
|
access: json.access_token,
|
|
@@ -5368,8 +5437,10 @@ function mapUsageWindow(window, checkedAt) {
|
|
|
5368
5437
|
async function fetchOAuthQuotaSnapshot(input) {
|
|
5369
5438
|
assertNotCustodyTombstone(input.accessToken, "anthropic");
|
|
5370
5439
|
const fetchImpl = input.fetchImpl ?? fetch;
|
|
5371
|
-
const
|
|
5440
|
+
const signal = auxiliaryRequestSignal();
|
|
5441
|
+
const response = await raceWithSignal(signal, () => fetchImpl(QUOTA_URL, {
|
|
5372
5442
|
method: "GET",
|
|
5443
|
+
signal,
|
|
5373
5444
|
redirect: "error",
|
|
5374
5445
|
headers: {
|
|
5375
5446
|
Authorization: `Bearer ${input.accessToken}`,
|
|
@@ -5378,9 +5449,9 @@ async function fetchOAuthQuotaSnapshot(input) {
|
|
|
5378
5449
|
"anthropic-beta": "oauth-2025-04-20",
|
|
5379
5450
|
"User-Agent": `claude-code/${CLAUDE_CODE_VERSION}`
|
|
5380
5451
|
}
|
|
5381
|
-
});
|
|
5452
|
+
}));
|
|
5382
5453
|
if (!response.ok) {
|
|
5383
|
-
const body = await response.text().catch(() => "");
|
|
5454
|
+
const body = await raceWithSignal(signal, () => response.text()).catch(() => "");
|
|
5384
5455
|
const error = Object.assign(new Error(`Claude quota check failed: ${response.status} — ${body}`), {
|
|
5385
5456
|
status: response.status,
|
|
5386
5457
|
retryAfter: parseRetryAfterHeader(response.headers.get("Retry-After"))
|
|
@@ -5388,7 +5459,7 @@ async function fetchOAuthQuotaSnapshot(input) {
|
|
|
5388
5459
|
throw error;
|
|
5389
5460
|
}
|
|
5390
5461
|
const checkedAt = input.now?.() ?? Date.now();
|
|
5391
|
-
const usage = await response.json();
|
|
5462
|
+
const usage = await raceWithSignal(signal, () => response.json());
|
|
5392
5463
|
const bindingWindow = mapBindingWindow(usage.limits);
|
|
5393
5464
|
const snapshot = {
|
|
5394
5465
|
five_hour: mapUsageWindow(usage.five_hour, checkedAt),
|
|
@@ -15013,11 +15084,12 @@ import { execFile } from "node:child_process";
|
|
|
15013
15084
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
15014
15085
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
15015
15086
|
import { lstat as lstat12, mkdir as mkdir10, readFile as readFile11 } from "node:fs/promises";
|
|
15087
|
+
import { uptime } from "node:os";
|
|
15016
15088
|
import { basename as basename9, dirname as dirname17, join as join20 } from "node:path";
|
|
15017
15089
|
|
|
15018
15090
|
// src/native-lock-observer.ts
|
|
15019
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
15020
|
-
var detachedLocks = new
|
|
15091
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
15092
|
+
var detachedLocks = new AsyncLocalStorage2;
|
|
15021
15093
|
function withDetachedNativeLocks(work) {
|
|
15022
15094
|
return detachedLocks.run(true, work);
|
|
15023
15095
|
}
|
|
@@ -15149,8 +15221,8 @@ function recordIdentityIn(tx, id, identity2) {
|
|
|
15149
15221
|
import { setTimeout as snapshotDelay } from "node:timers/promises";
|
|
15150
15222
|
|
|
15151
15223
|
// ../../node_modules/@cortexkit/common-auth/dist/store/hooks.js
|
|
15152
|
-
import { AsyncLocalStorage as
|
|
15153
|
-
var insideHook = new
|
|
15224
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
15225
|
+
var insideHook = new AsyncLocalStorage3;
|
|
15154
15226
|
function assertNotInsideHook(operation) {
|
|
15155
15227
|
if (insideHook.getStore() !== undefined)
|
|
15156
15228
|
throw new PoolReentryError(operation);
|
|
@@ -21408,11 +21480,13 @@ class StickySessionRouter {
|
|
|
21408
21480
|
})).sort((left, right) => left.score - right.score || left.candidate.order - right.candidate.order || left.candidate.accountId.localeCompare(right.candidate.accountId))[0]?.candidate;
|
|
21409
21481
|
}
|
|
21410
21482
|
async resolve(input) {
|
|
21483
|
+
requestSignal()?.throwIfAborted();
|
|
21411
21484
|
if (!input.sessionId)
|
|
21412
21485
|
return null;
|
|
21413
21486
|
this.recoverLocalPins();
|
|
21414
21487
|
await this.prepareLegacySeed();
|
|
21415
21488
|
await this.refreshStateIfChanged().catch(() => {});
|
|
21489
|
+
requestSignal()?.throwIfAborted();
|
|
21416
21490
|
const key = sessionKey(input.sessionId);
|
|
21417
21491
|
const affinityModelId = input.affinityModelId ?? input.modelId;
|
|
21418
21492
|
const matchesAffinity = (assignment2) => affinityModelId !== undefined ? assignment2.affinityModelId === affinityModelId : assignment2.family === input.family;
|
|
@@ -21429,10 +21503,12 @@ class StickySessionRouter {
|
|
|
21429
21503
|
const cached = this.state.assignments[key];
|
|
21430
21504
|
if (cached && this.assignmentIsActive(cached) && matchesAffinity(cached) && matchesAccountIdentity(cached) && input.retainAccountIds.has(this.logicalAccountId(cached)) && !input.excludeAccountIds?.has(this.logicalAccountId(cached))) {
|
|
21431
21505
|
if (this.now() - cached.lastSeenAt >= STICKY_ROUTING_TOUCH_INTERVAL_MS) {
|
|
21432
|
-
|
|
21433
|
-
|
|
21506
|
+
commitRequestChange(() => {
|
|
21507
|
+
cached.lastSeenAt = this.now();
|
|
21508
|
+
this.scheduleTouch(key);
|
|
21509
|
+
});
|
|
21434
21510
|
}
|
|
21435
|
-
this.retryChange(key);
|
|
21511
|
+
commitRequestChange(() => this.retryChange(key));
|
|
21436
21512
|
return {
|
|
21437
21513
|
accountId: this.logicalAccountId(cached),
|
|
21438
21514
|
assignment: { ...cached },
|
|
@@ -21442,7 +21518,7 @@ class StickySessionRouter {
|
|
|
21442
21518
|
}
|
|
21443
21519
|
const state = structuredClone(this.state);
|
|
21444
21520
|
const save = (operation) => {
|
|
21445
|
-
this.scheduleChange(key, state.assignments[key], operation);
|
|
21521
|
+
commitRequestChange(() => this.scheduleChange(key, state.assignments[key], operation));
|
|
21446
21522
|
};
|
|
21447
21523
|
this.prune(state);
|
|
21448
21524
|
const current = state.assignments[key];
|
|
@@ -22502,7 +22578,16 @@ var defaultLiveness = {
|
|
|
22502
22578
|
pidAlive,
|
|
22503
22579
|
incarnation: processIncarnation
|
|
22504
22580
|
};
|
|
22581
|
+
function recordPredatesBoot(startedAt, clock = {}) {
|
|
22582
|
+
if (typeof startedAt !== "number" || !Number.isFinite(startedAt) || startedAt < 0)
|
|
22583
|
+
return false;
|
|
22584
|
+
const now = (clock.now ?? Date.now)();
|
|
22585
|
+
const uptimeSeconds = (clock.uptime ?? uptime)();
|
|
22586
|
+
return Number.isFinite(now) && Number.isFinite(uptimeSeconds) && uptimeSeconds >= 0 && startedAt <= now && startedAt < now - uptimeSeconds * 1000 - 5 * 60000;
|
|
22587
|
+
}
|
|
22505
22588
|
async function holderEntryIsLive(entry2, liveness = defaultLiveness) {
|
|
22589
|
+
if (recordPredatesBoot(entry2.registeredAt, liveness))
|
|
22590
|
+
return false;
|
|
22506
22591
|
if (!liveness.pidAlive(entry2.pid))
|
|
22507
22592
|
return false;
|
|
22508
22593
|
if (entry2.incarnation === null)
|
|
@@ -22526,7 +22611,7 @@ function holderEntryLiveness(value) {
|
|
|
22526
22611
|
return;
|
|
22527
22612
|
if (incarnation !== null && typeof incarnation !== "string")
|
|
22528
22613
|
return;
|
|
22529
|
-
return { pid, incarnation };
|
|
22614
|
+
return { pid, incarnation, registeredAt: value.registeredAt };
|
|
22530
22615
|
}
|
|
22531
22616
|
function sameRegistration(value, entry2) {
|
|
22532
22617
|
if (!isRecord13(value))
|
|
@@ -22645,8 +22730,12 @@ async function publishHolderEntryLocked(holderFile, entry2, options) {
|
|
|
22645
22730
|
if (!life || await holderEntryIsLive(life, liveness))
|
|
22646
22731
|
kept.push(value);
|
|
22647
22732
|
}
|
|
22733
|
+
let changed = kept.length !== (current?.entries.length ?? 0);
|
|
22648
22734
|
if (!kept.some((value) => sameRegistration(value, entry2))) {
|
|
22649
22735
|
kept.push(entry2);
|
|
22736
|
+
changed = true;
|
|
22737
|
+
}
|
|
22738
|
+
if (changed) {
|
|
22650
22739
|
await writeJsonAtomic(holderFile, { version: 1, entries: kept }, { beforeRename: () => options.assertOwned() });
|
|
22651
22740
|
}
|
|
22652
22741
|
published.add(registrationKey(holderFile, entry2));
|
|
@@ -22989,20 +23078,21 @@ var PROFILE_URL = "https://api.anthropic.com/api/oauth/profile";
|
|
|
22989
23078
|
var PROFILE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
22990
23079
|
async function fetchOAuthAccountProfile(input) {
|
|
22991
23080
|
assertNotCustodyTombstone(input.accessToken, "anthropic");
|
|
22992
|
-
const
|
|
23081
|
+
const signal = auxiliaryRequestSignal(input.signal);
|
|
23082
|
+
const response = await raceWithSignal(signal, () => (input.fetchImpl ?? fetch)(PROFILE_URL, {
|
|
22993
23083
|
method: "GET",
|
|
22994
23084
|
redirect: "error",
|
|
22995
|
-
signal
|
|
23085
|
+
signal,
|
|
22996
23086
|
headers: {
|
|
22997
23087
|
Authorization: `Bearer ${input.accessToken}`,
|
|
22998
23088
|
Accept: "application/json",
|
|
22999
23089
|
"anthropic-beta": "oauth-2025-04-20"
|
|
23000
23090
|
}
|
|
23001
|
-
});
|
|
23091
|
+
}));
|
|
23002
23092
|
if (!response.ok) {
|
|
23003
23093
|
throw new Error(`Claude profile check failed: ${response.status}`);
|
|
23004
23094
|
}
|
|
23005
|
-
const value = await response.json();
|
|
23095
|
+
const value = await raceWithSignal(signal, () => response.json());
|
|
23006
23096
|
const tier = value.organization?.rate_limit_tier;
|
|
23007
23097
|
const orgType = value.organization?.organization_type;
|
|
23008
23098
|
if (typeof tier !== "string" || tier.trim() === "" || typeof orgType !== "string" || orgType.trim() === "") {
|
|
@@ -28633,7 +28723,10 @@ function createNativeVaultRuntime(options) {
|
|
|
28633
28723
|
const combined = signalFor(signal);
|
|
28634
28724
|
let served = await runtime2.authorize(routeId, combined);
|
|
28635
28725
|
const send = (input, init) => {
|
|
28636
|
-
const physical = () => fetchImpl(input, {
|
|
28726
|
+
const physical = () => fetchImpl(input, {
|
|
28727
|
+
...init,
|
|
28728
|
+
signal: init?.signal ? AbortSignal.any([combined, init.signal]) : combined
|
|
28729
|
+
});
|
|
28637
28730
|
if (!dispatch)
|
|
28638
28731
|
return physical();
|
|
28639
28732
|
return dispatch(physical, async () => {
|
|
@@ -29013,6 +29106,7 @@ function jsonHeaders(headers) {
|
|
|
29013
29106
|
return result;
|
|
29014
29107
|
}
|
|
29015
29108
|
async function postRelay(config, payload, signal) {
|
|
29109
|
+
signal?.throwIfAborted();
|
|
29016
29110
|
const stringifyStart = perfNowMs();
|
|
29017
29111
|
const body = JSON.stringify(payload);
|
|
29018
29112
|
relayPerfLog("http_payload_stringify", {
|
|
@@ -29266,10 +29360,11 @@ class PersistentRelaySession {
|
|
|
29266
29360
|
this.serverState = undefined;
|
|
29267
29361
|
this.connecting = undefined;
|
|
29268
29362
|
}
|
|
29269
|
-
send(payload, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, responseMode) {
|
|
29363
|
+
send(payload, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, responseMode, signal) {
|
|
29364
|
+
signal?.throwIfAborted();
|
|
29270
29365
|
this.touch();
|
|
29271
29366
|
const enqueuedAt = perfNowMs();
|
|
29272
|
-
const start = this.queue.catch(() => {}).then(() => this.startQueued(payload, bodyText, enqueuedAt, optimisticResponse, onResponseHeaders, authorizeAttempt, responseMode));
|
|
29367
|
+
const start = this.queue.catch(() => {}).then(() => raceWithSignal(signal, () => this.startQueued(payload, bodyText, enqueuedAt, optimisticResponse, onResponseHeaders, authorizeAttempt, responseMode, signal)));
|
|
29273
29368
|
const result = start.then(async ({ response, getPayload }) => ({
|
|
29274
29369
|
response: await response,
|
|
29275
29370
|
payload: getPayload(),
|
|
@@ -29278,12 +29373,14 @@ class PersistentRelaySession {
|
|
|
29278
29373
|
usedRelay: true
|
|
29279
29374
|
}));
|
|
29280
29375
|
this.queue = start.then(({ done }) => done.catch(() => {}), () => {});
|
|
29281
|
-
return result;
|
|
29376
|
+
return raceWithSignal(signal, () => result);
|
|
29282
29377
|
}
|
|
29283
|
-
async startQueued(payload, bodyText, enqueuedAt, optimisticResponse, onResponseHeaders, authorizeAttempt, responseMode) {
|
|
29378
|
+
async startQueued(payload, bodyText, enqueuedAt, optimisticResponse, onResponseHeaders, authorizeAttempt, responseMode, signal) {
|
|
29379
|
+
signal?.throwIfAborted();
|
|
29284
29380
|
const createScopes = (secrets) => createWebSocketAttemptScopes(secrets, responseMode);
|
|
29285
29381
|
const connectStart = perfNowMs();
|
|
29286
29382
|
await this.ensureConnected();
|
|
29383
|
+
signal?.throwIfAborted();
|
|
29287
29384
|
const connectedAt = perfNowMs();
|
|
29288
29385
|
const localState = sessionState.get(this.affinity);
|
|
29289
29386
|
const serverHash = this.serverState?.hash;
|
|
@@ -29304,8 +29401,12 @@ class PersistentRelaySession {
|
|
|
29304
29401
|
}
|
|
29305
29402
|
relayLog(`perf websocket send_start session=${shortAffinity2(this.affinity)} request=${requestPayload.id} mode=${requestPayload.mode} queueMs=${formatMs(connectedAt - enqueuedAt)} connectMs=${formatMs(connectedAt - connectStart)} bodyBytes=${bodyText.length} relayBytes=${JSON.stringify(requestPayload).length}`);
|
|
29306
29403
|
const firstAttempt = await authorizePhysicalAttempt(this.config, requestPayload, authorizeAttempt, createScopes);
|
|
29404
|
+
if (signal?.aborted) {
|
|
29405
|
+
disposeWebSocketAttemptScopes(firstAttempt.scope);
|
|
29406
|
+
signal.throwIfAborted();
|
|
29407
|
+
}
|
|
29307
29408
|
let activePayload = requestPayload;
|
|
29308
|
-
const first = this.sendPayload(requestPayload, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, firstAttempt, responseMode);
|
|
29409
|
+
const first = this.sendPayload(requestPayload, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, firstAttempt, responseMode, signal);
|
|
29309
29410
|
first.done.catch(() => {});
|
|
29310
29411
|
let activeDone = first.done;
|
|
29311
29412
|
const response = first.response.catch(async (error) => {
|
|
@@ -29317,13 +29418,18 @@ class PersistentRelaySession {
|
|
|
29317
29418
|
fullSync.id = createRequestId();
|
|
29318
29419
|
fullSync.revision = (this.serverState?.revision ?? 0) + 1;
|
|
29319
29420
|
const retryAttempt = await authorizePhysicalAttempt(this.config, fullSync, authorizeAttempt, createScopes);
|
|
29421
|
+
if (signal?.aborted) {
|
|
29422
|
+
disposeWebSocketAttemptScopes(retryAttempt.scope);
|
|
29423
|
+
signal.throwIfAborted();
|
|
29424
|
+
}
|
|
29320
29425
|
activePayload = fullSync;
|
|
29321
|
-
const retry = this.sendPayload(fullSync, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, retryAttempt, responseMode);
|
|
29426
|
+
const retry = this.sendPayload(fullSync, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, retryAttempt, responseMode, signal);
|
|
29322
29427
|
retry.done.catch(() => {});
|
|
29323
29428
|
activeDone = retry.done;
|
|
29324
29429
|
return retry.response;
|
|
29325
29430
|
});
|
|
29326
29431
|
const done = response.then(() => activeDone, () => activeDone.catch(() => {}));
|
|
29432
|
+
done.catch(() => {});
|
|
29327
29433
|
return { response, done, getPayload: () => activePayload };
|
|
29328
29434
|
}
|
|
29329
29435
|
async ensureConnected() {
|
|
@@ -29396,7 +29502,7 @@ class PersistentRelaySession {
|
|
|
29396
29502
|
});
|
|
29397
29503
|
await this.connecting;
|
|
29398
29504
|
}
|
|
29399
|
-
sendPayload(payload, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, attempt, responseMode) {
|
|
29505
|
+
sendPayload(payload, bodyText, optimisticResponse, onResponseHeaders, authorizeAttempt, attempt, responseMode, signal) {
|
|
29400
29506
|
const socket = this.socket;
|
|
29401
29507
|
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
29402
29508
|
disposeWebSocketAttemptScopes(attempt.scope);
|
|
@@ -29438,6 +29544,24 @@ class PersistentRelaySession {
|
|
|
29438
29544
|
responseHeadersDelivered: false
|
|
29439
29545
|
};
|
|
29440
29546
|
this.pending = pending;
|
|
29547
|
+
if (signal) {
|
|
29548
|
+
const abort = () => {
|
|
29549
|
+
if (this.pending !== pending)
|
|
29550
|
+
return;
|
|
29551
|
+
this.failPending(signal.reason, false);
|
|
29552
|
+
const socket2 = this.socket;
|
|
29553
|
+
this.socket = undefined;
|
|
29554
|
+
this.serverState = undefined;
|
|
29555
|
+
this.connecting = undefined;
|
|
29556
|
+
socket2?.close();
|
|
29557
|
+
};
|
|
29558
|
+
pending.abortCleanup = () => signal.removeEventListener("abort", abort);
|
|
29559
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
29560
|
+
if (signal.aborted) {
|
|
29561
|
+
abort();
|
|
29562
|
+
return;
|
|
29563
|
+
}
|
|
29564
|
+
}
|
|
29441
29565
|
this.resetPendingTimeout(pending);
|
|
29442
29566
|
socket.send(JSON.stringify(payload));
|
|
29443
29567
|
if (optimisticResponse) {
|
|
@@ -29540,6 +29664,8 @@ class PersistentRelaySession {
|
|
|
29540
29664
|
}
|
|
29541
29665
|
retireAttempt(pending) {
|
|
29542
29666
|
pending.retired = true;
|
|
29667
|
+
pending.abortCleanup?.();
|
|
29668
|
+
pending.abortCleanup = undefined;
|
|
29543
29669
|
pending.scope?.dispose();
|
|
29544
29670
|
pending.scope = undefined;
|
|
29545
29671
|
pending.responseScope?.dispose();
|
|
@@ -29936,8 +30062,9 @@ async function sendViaRelay(options) {
|
|
|
29936
30062
|
clearTimeout: clearTimeoutImpl
|
|
29937
30063
|
});
|
|
29938
30064
|
const optimistic = optimisticResponse === true && requestMode() === "event-stream";
|
|
29939
|
-
result = await session.send(payload, bodyText, optimistic, onResponseHeaders, authorizeAttempt, requestMode());
|
|
30065
|
+
result = await session.send(payload, bodyText, optimistic, onResponseHeaders, authorizeAttempt, requestMode(), init?.signal);
|
|
29940
30066
|
} catch (error) {
|
|
30067
|
+
init?.signal?.throwIfAborted();
|
|
29941
30068
|
if (error instanceof RelayAuthorizationError || error instanceof RelayResponseMetadataError)
|
|
29942
30069
|
throw error;
|
|
29943
30070
|
relayLog(`websocket relay failed session=${shortAffinity2(affinity)}; trying http relay code=relay_transport_error`);
|
|
@@ -30013,6 +30140,7 @@ async function sendViaRelay(options) {
|
|
|
30013
30140
|
});
|
|
30014
30141
|
return result.response;
|
|
30015
30142
|
} catch (error) {
|
|
30143
|
+
init?.signal?.throwIfAborted();
|
|
30016
30144
|
if (error instanceof RelayAuthorizationError)
|
|
30017
30145
|
throw error.failure;
|
|
30018
30146
|
if (error instanceof RelayResponseMetadataError)
|
|
@@ -31470,7 +31598,10 @@ function createNativeAccountRuntime(options) {
|
|
|
31470
31598
|
throw new NativeCustodyError("route-unavailable");
|
|
31471
31599
|
let served = first;
|
|
31472
31600
|
const send = (input, init) => {
|
|
31473
|
-
const physical = () => fetchImpl(input, {
|
|
31601
|
+
const physical = () => fetchImpl(input, {
|
|
31602
|
+
...init,
|
|
31603
|
+
signal: init?.signal ? AbortSignal.any([combined, init.signal]) : combined
|
|
31604
|
+
});
|
|
31474
31605
|
if (!dispatch)
|
|
31475
31606
|
return physical();
|
|
31476
31607
|
return dispatch(physical, async () => {
|
|
@@ -35561,6 +35692,8 @@ function fetchInputUrl(input) {
|
|
|
35561
35692
|
function createAnthropicOAuthFetch(options = {}) {
|
|
35562
35693
|
const current = () => typeof options === "function" ? options() : options;
|
|
35563
35694
|
return Object.assign(async (input, init) => {
|
|
35695
|
+
const signal = init?.signal !== undefined ? init.signal : input instanceof Request ? input.signal : undefined;
|
|
35696
|
+
signal?.throwIfAborted();
|
|
35564
35697
|
requireAnthropicOAuthOrigin(fetchInputUrl(input), current());
|
|
35565
35698
|
return fetch(input, { ...init, redirect: "error" });
|
|
35566
35699
|
}, {
|
|
@@ -37167,7 +37300,7 @@ import { homedir as homedir7 } from "node:os";
|
|
|
37167
37300
|
import { basename as basename13, dirname as dirname24, join as join30 } from "node:path";
|
|
37168
37301
|
|
|
37169
37302
|
// src/layout-fence.ts
|
|
37170
|
-
import {
|
|
37303
|
+
import { open as open13, readdir as readdir6 } from "node:fs/promises";
|
|
37171
37304
|
import { homedir as homedir5 } from "node:os";
|
|
37172
37305
|
import { basename as basename11, join as join27, resolve as resolve18 } from "node:path";
|
|
37173
37306
|
var STATE_PATH_OVERRIDE_VARIABLES = [
|
|
@@ -37285,8 +37418,15 @@ function stamped(value) {
|
|
|
37285
37418
|
}
|
|
37286
37419
|
async function readArtifact(path2, blockers) {
|
|
37287
37420
|
let text6;
|
|
37421
|
+
let mtimeMs;
|
|
37288
37422
|
try {
|
|
37289
|
-
|
|
37423
|
+
const file = await open13(path2, "r");
|
|
37424
|
+
try {
|
|
37425
|
+
text6 = await file.readFile("utf8");
|
|
37426
|
+
mtimeMs = (await file.stat()).mtimeMs;
|
|
37427
|
+
} finally {
|
|
37428
|
+
await file.close();
|
|
37429
|
+
}
|
|
37290
37430
|
} catch (error) {
|
|
37291
37431
|
if (errorCode5(error) === "ENOENT")
|
|
37292
37432
|
return;
|
|
@@ -37294,13 +37434,15 @@ async function readArtifact(path2, blockers) {
|
|
|
37294
37434
|
return;
|
|
37295
37435
|
}
|
|
37296
37436
|
try {
|
|
37297
|
-
|
|
37437
|
+
const value = JSON.parse(text6);
|
|
37438
|
+
const startedAt = typeof value === "object" && value !== null ? "startedAt" in value ? value.startedAt : ("registeredAt" in value) ? value.registeredAt : mtimeMs : mtimeMs;
|
|
37439
|
+
return { value, startedAt };
|
|
37298
37440
|
} catch {
|
|
37299
37441
|
blockers.push({ kind: "artifact-scan", path: path2, reason: "invalid" });
|
|
37300
37442
|
return;
|
|
37301
37443
|
}
|
|
37302
37444
|
}
|
|
37303
|
-
async function preNArtifactBlockers(locations, pidAlive2 = defaultLiveness2.pidAlive) {
|
|
37445
|
+
async function preNArtifactBlockers(locations, pidAlive2 = defaultLiveness2.pidAlive, clock = {}) {
|
|
37304
37446
|
const blockers = [];
|
|
37305
37447
|
const portDirs = [...locations.rpcDirs];
|
|
37306
37448
|
for (const root of locations.rpcRoots)
|
|
@@ -37311,15 +37453,16 @@ async function preNArtifactBlockers(locations, pidAlive2 = defaultLiveness2.pidA
|
|
|
37311
37453
|
if (!/^port-\d+\.json$/.test(name))
|
|
37312
37454
|
continue;
|
|
37313
37455
|
const path2 = join27(dir, name);
|
|
37314
|
-
const
|
|
37315
|
-
if (
|
|
37456
|
+
const record9 = await readArtifact(path2, blockers);
|
|
37457
|
+
if (record9 === undefined || stamped(record9.value))
|
|
37316
37458
|
continue;
|
|
37459
|
+
const { value, startedAt } = record9;
|
|
37317
37460
|
const pid = value.pid;
|
|
37318
37461
|
if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid <= 0) {
|
|
37319
37462
|
blockers.push({ kind: "artifact-scan", path: path2, reason: "invalid" });
|
|
37320
37463
|
continue;
|
|
37321
37464
|
}
|
|
37322
|
-
if (pidAlive2(pid))
|
|
37465
|
+
if (!recordPredatesBoot(startedAt, clock) && pidAlive2(pid))
|
|
37323
37466
|
blockers.push({ kind: "pre-n-artifact", artifact: path2, pid });
|
|
37324
37467
|
}
|
|
37325
37468
|
}
|
|
@@ -37329,11 +37472,11 @@ async function preNArtifactBlockers(locations, pidAlive2 = defaultLiveness2.pidA
|
|
|
37329
37472
|
if (!match)
|
|
37330
37473
|
continue;
|
|
37331
37474
|
const path2 = join27(dir, name);
|
|
37332
|
-
const
|
|
37333
|
-
if (
|
|
37475
|
+
const record9 = await readArtifact(path2, blockers);
|
|
37476
|
+
if (record9 === undefined || stamped(record9.value))
|
|
37334
37477
|
continue;
|
|
37335
37478
|
const pid = Number(match[1]);
|
|
37336
|
-
if (pidAlive2(pid))
|
|
37479
|
+
if (!recordPredatesBoot(record9.startedAt, clock) && pidAlive2(pid))
|
|
37337
37480
|
blockers.push({ kind: "pre-n-artifact", artifact: path2, pid });
|
|
37338
37481
|
}
|
|
37339
37482
|
}
|
|
@@ -37356,7 +37499,7 @@ function describeFenceBlocker(blocker) {
|
|
|
37356
37499
|
|
|
37357
37500
|
// src/state-layout-move.ts
|
|
37358
37501
|
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
37359
|
-
import { lstat as lstat18, readdir as readdir7, readFile as
|
|
37502
|
+
import { lstat as lstat18, readdir as readdir7, readFile as readFile15, stat as stat13, unlink as unlink10 } from "node:fs/promises";
|
|
37360
37503
|
import { basename as basename12, dirname as dirname23, join as join28, sep as sep2 } from "node:path";
|
|
37361
37504
|
var ACCOUNT_FILE = "anthropic-auth.json";
|
|
37362
37505
|
var ACCOUNT_STATE_FILE = "anthropic-auth-state.json";
|
|
@@ -37826,7 +37969,7 @@ async function rollbackPreparing(record9, dataset, ctx) {
|
|
|
37826
37969
|
} else {
|
|
37827
37970
|
let copy;
|
|
37828
37971
|
try {
|
|
37829
|
-
copy = await
|
|
37972
|
+
copy = await readFile15(file.to);
|
|
37830
37973
|
} catch {
|
|
37831
37974
|
throw new StateLayoutRollbackRefused(file.to, `its copy, needed to undo the tombstone over ${file.from}, is missing`);
|
|
37832
37975
|
}
|
|
@@ -38017,12 +38160,12 @@ async function moveDataset(dataset, ctx, checkArtifacts) {
|
|
|
38017
38160
|
for (const file of files) {
|
|
38018
38161
|
if (file.sha256 === null)
|
|
38019
38162
|
continue;
|
|
38020
|
-
const bytes = await
|
|
38163
|
+
const bytes = await readFile15(file.from);
|
|
38021
38164
|
if (sha256Hex(bytes) !== file.sha256)
|
|
38022
38165
|
throw new MoveRefused(`${file.from} changed while it was copied`);
|
|
38023
38166
|
const stage = relocatingPath(file.to, attempt);
|
|
38024
38167
|
await createOwnerOnlyFile(ctx.fs, stage, bytes);
|
|
38025
|
-
const back = await
|
|
38168
|
+
const back = await readFile15(stage);
|
|
38026
38169
|
if (!back.equals(bytes))
|
|
38027
38170
|
throw new MoveRefused(`the copy of ${file.from} reads back differently`);
|
|
38028
38171
|
await owned2(ctx, { kind: "rename", from: stage, to: file.to }, expectAbsent(file.to));
|
|
@@ -38134,7 +38277,7 @@ async function rollbackAfterFailure(preparing, dataset, ctx) {
|
|
|
38134
38277
|
|
|
38135
38278
|
// src/state-layout-restore.ts
|
|
38136
38279
|
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
38137
|
-
import { readFile as
|
|
38280
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
38138
38281
|
import { homedir as homedir6 } from "node:os";
|
|
38139
38282
|
import { join as join29 } from "node:path";
|
|
38140
38283
|
var DATA_ROLES = [
|
|
@@ -38414,7 +38557,7 @@ async function newRestoreProblems(record9, dataset, options) {
|
|
|
38414
38557
|
}
|
|
38415
38558
|
problems.push(...await holderProblems(join29(dataset.sub, HOLDER_FILE_NAME), options.liveness, true), ...await holderProblems(join29(dataset.oldDir, HOLDER_FILE_NAME), options.liveness, false));
|
|
38416
38559
|
const artifacts = options.artifacts ?? defaultPreNArtifactLocations(options.env ?? process.env, options.home ?? homedir6());
|
|
38417
|
-
for (const blocker of await preNArtifactBlockers(artifacts, options.liveness?.pidAlive))
|
|
38560
|
+
for (const blocker of await preNArtifactBlockers(artifacts, options.liveness?.pidAlive, options.liveness))
|
|
38418
38561
|
problems.push(`${describeFenceBlocker(blocker)} is still running`);
|
|
38419
38562
|
for (const slot of dataset.slots) {
|
|
38420
38563
|
if (slot.role === "localRuntime" || slot.role === "vaultRuntime") {
|
|
@@ -38478,12 +38621,12 @@ async function startRestore(record9, dataset, ctx, options) {
|
|
|
38478
38621
|
}, ctx.fs);
|
|
38479
38622
|
await stateLayoutStep(ctx, "restore:restoring-written");
|
|
38480
38623
|
for (const file of files) {
|
|
38481
|
-
const bytes = await
|
|
38624
|
+
const bytes = await readFile16(file.to);
|
|
38482
38625
|
if (sha256Hex(bytes) !== file.sha256)
|
|
38483
38626
|
throw refused2(`${file.to} changed while it was being restored; run ${RESTORE_LEGACY_COMMAND} again.`, [file.to]);
|
|
38484
38627
|
await ctx.stack.assertAll();
|
|
38485
38628
|
await createOwnerOnlyFile(ctx.fs, file.staging, bytes);
|
|
38486
|
-
const back = await
|
|
38629
|
+
const back = await readFile16(file.staging);
|
|
38487
38630
|
if (!back.equals(bytes))
|
|
38488
38631
|
throw refused2(`the restored copy of ${file.to} reads back differently; run ${RESTORE_LEGACY_COMMAND} again.`, [file.staging]);
|
|
38489
38632
|
await stateLayoutStep(ctx, `restore:staged:${file.role}`);
|
|
@@ -39137,7 +39280,7 @@ async function underLayoutLock(dataset, options, ctx, overrides, neverMove) {
|
|
|
39137
39280
|
const files = [...dataset.slots.flatMap((slot) => [slot.from, slot.to])];
|
|
39138
39281
|
const artifacts = options.artifacts ?? defaultPreNArtifactLocations(options.env ?? process.env, options.home ?? homedir7());
|
|
39139
39282
|
const checkArtifacts = async () => {
|
|
39140
|
-
const found = await preNArtifactBlockers(artifacts, options.liveness?.pidAlive);
|
|
39283
|
+
const found = await preNArtifactBlockers(artifacts, options.liveness?.pidAlive, options.liveness);
|
|
39141
39284
|
return found.length ? found.map(describeFenceBlocker).join("; ") : undefined;
|
|
39142
39285
|
};
|
|
39143
39286
|
const blockers = [
|
|
@@ -39146,7 +39289,7 @@ async function underLayoutLock(dataset, options, ctx, overrides, neverMove) {
|
|
|
39146
39289
|
files,
|
|
39147
39290
|
liveness: options.liveness
|
|
39148
39291
|
}),
|
|
39149
|
-
...await preNArtifactBlockers(artifacts, options.liveness?.pidAlive)
|
|
39292
|
+
...await preNArtifactBlockers(artifacts, options.liveness?.pidAlive, options.liveness)
|
|
39150
39293
|
].map(describeFenceBlocker);
|
|
39151
39294
|
if (!blockers.length) {
|
|
39152
39295
|
const failure2 = await movePreconditionFailure(dataset, ctx.fs.platform);
|
|
@@ -39349,6 +39492,7 @@ export {
|
|
|
39349
39492
|
writerStamp,
|
|
39350
39493
|
writeNativeHostAuth,
|
|
39351
39494
|
writeDumpFile,
|
|
39495
|
+
withAbortableFetch,
|
|
39352
39496
|
usesPerTurnControl,
|
|
39353
39497
|
usagePublicationRefusalIsFatal,
|
|
39354
39498
|
unmovedRegistrationPolicy,
|
|
@@ -39396,6 +39540,7 @@ export {
|
|
|
39396
39540
|
sendWithRequestGzip,
|
|
39397
39541
|
sendViaRelay,
|
|
39398
39542
|
selectClaudeCodeBetas,
|
|
39543
|
+
runWithRequestSignal,
|
|
39399
39544
|
runSetup,
|
|
39400
39545
|
runPiCommandMenu,
|
|
39401
39546
|
runNativeMigration,
|
|
@@ -39419,6 +39564,7 @@ export {
|
|
|
39419
39564
|
resetBillingHeaderCCH,
|
|
39420
39565
|
requireNoSupervisedAuthContentSnapshot,
|
|
39421
39566
|
requireAnthropicOAuthOrigin,
|
|
39567
|
+
requestSignal,
|
|
39422
39568
|
requestGzipPadding,
|
|
39423
39569
|
reportRouting,
|
|
39424
39570
|
renameWithWindowsSharingRetry,
|
|
@@ -39432,6 +39578,7 @@ export {
|
|
|
39432
39578
|
refreshBackoffActive,
|
|
39433
39579
|
redactPayload,
|
|
39434
39580
|
recordProcessStateLayout,
|
|
39581
|
+
recordPredatesBoot,
|
|
39435
39582
|
readWindowsOwnerOnly,
|
|
39436
39583
|
readStateLayoutMarker,
|
|
39437
39584
|
readRelocationPointer,
|
|
@@ -39443,6 +39590,7 @@ export {
|
|
|
39443
39590
|
readConfigDirMarker,
|
|
39444
39591
|
readClaustrumEnrollmentToken2 as readClaustrumEnrollmentToken,
|
|
39445
39592
|
readClaustrumEnrollmentStatus2 as readClaustrumEnrollmentStatus,
|
|
39593
|
+
raceWithSignal,
|
|
39446
39594
|
quotaWindowParts,
|
|
39447
39595
|
quotaTextParts,
|
|
39448
39596
|
quotaSnapshotPassesPolicy,
|
|
@@ -39701,6 +39849,7 @@ export {
|
|
|
39701
39849
|
computeXxhash64Hex,
|
|
39702
39850
|
computeCcVersionSuffix,
|
|
39703
39851
|
computeCCH,
|
|
39852
|
+
commitRequestChange,
|
|
39704
39853
|
claudeCodeEntrypoint,
|
|
39705
39854
|
classifySafeErrorForLog,
|
|
39706
39855
|
classifyGzipRejection,
|
|
@@ -39726,6 +39875,7 @@ export {
|
|
|
39726
39875
|
buildCache1hStatusSummary,
|
|
39727
39876
|
buildBillingHeaderValue,
|
|
39728
39877
|
buildAccountList,
|
|
39878
|
+
auxiliaryRequestSignal,
|
|
39729
39879
|
authorize,
|
|
39730
39880
|
assertUnmanagedInjectedPaths,
|
|
39731
39881
|
assertNotCustodyTombstone,
|
|
@@ -39743,6 +39893,7 @@ export {
|
|
|
39743
39893
|
acquireRefreshFileLock2 as acquireRefreshFileLock,
|
|
39744
39894
|
acquireNativeVaultRuntime,
|
|
39745
39895
|
acquireNativeAccountRuntime,
|
|
39896
|
+
abortableFetch,
|
|
39746
39897
|
__setLogTestSink,
|
|
39747
39898
|
WORKER_SCRIPT,
|
|
39748
39899
|
USER_AGENT,
|
|
@@ -39920,6 +40071,7 @@ export {
|
|
|
39920
40071
|
CACHE_1H_COMMAND_NAME,
|
|
39921
40072
|
AnthropicOAuthOriginError,
|
|
39922
40073
|
AXIOS_USER_AGENT,
|
|
40074
|
+
AUXILIARY_REQUEST_TIMEOUT_MS,
|
|
39923
40075
|
AUTHORIZE_URLS,
|
|
39924
40076
|
ANTHROPIC_OAUTH_ORIGIN_REFUSAL,
|
|
39925
40077
|
ANTHROPIC_OAUTH_ORIGIN,
|
package/dist/layout-fence.d.ts
CHANGED
|
@@ -58,8 +58,9 @@ export declare function defaultPreNArtifactLocations(env?: NodeJS.ProcessEnv, ho
|
|
|
58
58
|
* The fence's check for older versions: an RPC port file or CacheKeep record without the
|
|
59
59
|
* `writer` stamp, whose pid is alive, belongs to a version that registers
|
|
60
60
|
* nothing and blocks. Every entry is read; a folder or file that can't be
|
|
61
|
-
* read or parsed blocks too.
|
|
61
|
+
* read or parsed blocks too. A record from before this boot is stale even
|
|
62
|
+
* if its pid has been reused; missing or untrustworthy times keep blocking.
|
|
62
63
|
*/
|
|
63
|
-
export declare function preNArtifactBlockers(locations: PreNArtifactLocations, pidAlive?: (pid: number) => boolean): Promise<FenceBlocker[]>;
|
|
64
|
+
export declare function preNArtifactBlockers(locations: PreNArtifactLocations, pidAlive?: (pid: number) => boolean, clock?: Pick<HolderLiveness, 'now' | 'uptime'>): Promise<FenceBlocker[]>;
|
|
64
65
|
/** One line naming a blocker, for the log. */
|
|
65
66
|
export declare function describeFenceBlocker(blocker: FenceBlocker): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End a caller's wait without cancelling shared work such as a token refresh.
|
|
3
|
+
* The operation still owns its cleanup and any late rejection is observed.
|
|
4
|
+
*/
|
|
5
|
+
export declare function raceWithSignal<T>(signal: AbortSignal | null | undefined, operation: () => Promise<T>): Promise<T>;
|
|
6
|
+
export declare function abortableFetch(send: (input: string | URL | Request, init?: RequestInit) => Promise<Response>): (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
7
|
+
export declare function withAbortableFetch<T extends {
|
|
8
|
+
fetch: Parameters<typeof abortableFetch>[0];
|
|
9
|
+
}>(options: T): T;
|
|
10
|
+
export declare const AUXILIARY_REQUEST_TIMEOUT_MS = 30000;
|
|
11
|
+
/** Account checks must finish even when no host request is waiting on them. */
|
|
12
|
+
export declare function auxiliaryRequestSignal(signal?: AbortSignal | null): AbortSignal;
|
|
13
|
+
export declare function requestSignal(): AbortSignal | null | undefined;
|
|
14
|
+
/** Publish request-owned routing changes only after preparation succeeds. */
|
|
15
|
+
export declare function commitRequestChange(commit: () => void): void;
|
|
16
|
+
export declare function runWithRequestSignal<T>(signal: AbortSignal | null | undefined, operation: () => Promise<T>): Promise<T>;
|