@cortexkit/anthropic-auth-core 2.2.1 → 2.2.2
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.js +524 -242
- package/dist/internal-types/claustrum/consumer.d.ts +3 -1
- 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/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/process-fence.d.ts +7 -0
- package/dist/native-vault-runtime.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -644,6 +644,7 @@ class LockOwnershipError extends Error {
|
|
|
644
644
|
async function withLock(target, options, fn) {
|
|
645
645
|
const started = performance.now();
|
|
646
646
|
for (;; ) {
|
|
647
|
+
options.signal?.throwIfAborted();
|
|
647
648
|
const lock = await acquireRefreshFileLock({
|
|
648
649
|
path: target,
|
|
649
650
|
name: options.name,
|
|
@@ -654,6 +655,7 @@ async function withLock(target, options, fn) {
|
|
|
654
655
|
});
|
|
655
656
|
if (lock) {
|
|
656
657
|
try {
|
|
658
|
+
options.signal?.throwIfAborted();
|
|
657
659
|
return await fn(lock);
|
|
658
660
|
} finally {
|
|
659
661
|
await lock.release();
|
|
@@ -2530,6 +2532,7 @@ Please quit all OpenCode, LiteCode, and Pi processes before running setup.`);
|
|
|
2530
2532
|
}
|
|
2531
2533
|
async function listSetupProcesses(runner = defaultCommandRunner, options = {}) {
|
|
2532
2534
|
const windows = (options.platform ?? process.platform) === "win32";
|
|
2535
|
+
const selfPid = options.selfPid ?? process.pid;
|
|
2533
2536
|
let inspection = {
|
|
2534
2537
|
step: windows ? "tasklist" : "ps",
|
|
2535
2538
|
exitCode: null,
|
|
@@ -2598,7 +2601,7 @@ async function listSetupProcesses(runner = defaultCommandRunner, options = {}) {
|
|
|
2598
2601
|
}
|
|
2599
2602
|
if (!processes.length)
|
|
2600
2603
|
throw new ProcessInspectionError(inspection);
|
|
2601
|
-
const runtimes = processes.filter((entry) => entry.pid !==
|
|
2604
|
+
const runtimes = processes.filter((entry) => entry.pid !== selfPid && /^(?:node|bun)\.exe$/i.test(entry.command));
|
|
2602
2605
|
if (windows && runtimes.length && options.inspectRuntimes !== false) {
|
|
2603
2606
|
const details = await inspect("CIM", "powershell.exe", [
|
|
2604
2607
|
"-NoProfile",
|
|
@@ -2631,7 +2634,8 @@ async function listSetupProcesses(runner = defaultCommandRunner, options = {}) {
|
|
|
2631
2634
|
}
|
|
2632
2635
|
}
|
|
2633
2636
|
function createProcessFence(runner = defaultCommandRunner, options = {}) {
|
|
2634
|
-
const
|
|
2637
|
+
const selfPid = options.selfPid ?? process.pid;
|
|
2638
|
+
const isHost = (entry) => entry.pid !== selfPid && hostName(entry.command) !== null;
|
|
2635
2639
|
return {
|
|
2636
2640
|
async listRunningHosts(env) {
|
|
2637
2641
|
return (await listSetupProcesses(runner, { ...options, env })).filter(isHost);
|
|
@@ -2645,7 +2649,7 @@ function createProcessFence(runner = defaultCommandRunner, options = {}) {
|
|
|
2645
2649
|
const windows = (options.platform ?? process.platform) === "win32";
|
|
2646
2650
|
return {
|
|
2647
2651
|
hosts: processes.filter(isHost),
|
|
2648
|
-
uncheckedRuntimes: windows ? processes.filter((entry) => entry.pid !==
|
|
2652
|
+
uncheckedRuntimes: windows ? processes.filter((entry) => entry.pid !== selfPid && /^(?:node|bun)\.exe$/i.test(entry.command)).length : 0
|
|
2649
2653
|
};
|
|
2650
2654
|
}
|
|
2651
2655
|
};
|
|
@@ -13272,6 +13276,12 @@ function isQuotaCounter(value) {
|
|
|
13272
13276
|
function isQuotaCounters(value) {
|
|
13273
13277
|
return isRecord8(value) && Object.values(value).every(isQuotaCounter);
|
|
13274
13278
|
}
|
|
13279
|
+
function isBoolean(value) {
|
|
13280
|
+
return typeof value === "boolean";
|
|
13281
|
+
}
|
|
13282
|
+
function isQuotaCredits(value) {
|
|
13283
|
+
return isRecord8(value) && typeof value.hasCredits === "boolean" && typeof value.unlimited === "boolean" && optional(value, "balance", isFiniteNumber) && optional(value, "overageLimitReached", isBoolean) && isFiniteNumber(value.checkedAt);
|
|
13284
|
+
}
|
|
13275
13285
|
function readQuotaCounters(value) {
|
|
13276
13286
|
if (!isRecord8(value))
|
|
13277
13287
|
return;
|
|
@@ -13283,11 +13293,16 @@ function decodeQuotaMap(value) {
|
|
|
13283
13293
|
return value;
|
|
13284
13294
|
if (!isRecord8(value))
|
|
13285
13295
|
return;
|
|
13286
|
-
const { counters: rawCounters, ...rest } = value;
|
|
13296
|
+
const { counters: rawCounters, credits: rawCredits, ...rest } = value;
|
|
13287
13297
|
if (!isQuotaMap(rest))
|
|
13288
13298
|
return;
|
|
13289
13299
|
const counters = readQuotaCounters(rawCounters);
|
|
13290
|
-
|
|
13300
|
+
const credits = isQuotaCredits(rawCredits) ? rawCredits : undefined;
|
|
13301
|
+
return {
|
|
13302
|
+
...rest,
|
|
13303
|
+
...counters === undefined ? {} : { counters },
|
|
13304
|
+
...credits === undefined ? {} : { credits }
|
|
13305
|
+
};
|
|
13291
13306
|
}
|
|
13292
13307
|
function isQuotaMap(value) {
|
|
13293
13308
|
if (!isRecord8(value) || !Array.isArray(value.limits))
|
|
@@ -13301,7 +13316,7 @@ function isQuotaMap(value) {
|
|
|
13301
13316
|
return false;
|
|
13302
13317
|
seen.add(key);
|
|
13303
13318
|
}
|
|
13304
|
-
return optional(value, "budget", isCreditBudgetEntry) && optional(value, "counters", isQuotaCounters);
|
|
13319
|
+
return optional(value, "budget", isCreditBudgetEntry) && optional(value, "counters", isQuotaCounters) && optional(value, "credits", isQuotaCredits);
|
|
13305
13320
|
}
|
|
13306
13321
|
|
|
13307
13322
|
// ../../node_modules/@cortexkit/common-auth/dist/quota/merge.js
|
|
@@ -13360,7 +13375,7 @@ function isQuotaObservation(value) {
|
|
|
13360
13375
|
}
|
|
13361
13376
|
if (!coverage.every(isObservedPair))
|
|
13362
13377
|
return false;
|
|
13363
|
-
return (value.budget === undefined || isObservedBudget(value.budget)) && (value.counters === undefined || isQuotaCounters(value.counters));
|
|
13378
|
+
return (value.budget === undefined || isObservedBudget(value.budget)) && (value.counters === undefined || isQuotaCounters(value.counters)) && (value.credits === undefined || isQuotaCredits(value.credits));
|
|
13364
13379
|
}
|
|
13365
13380
|
function compareEntries(left, right) {
|
|
13366
13381
|
if (left.scope !== right.scope)
|
|
@@ -13386,6 +13401,14 @@ function mergeCounters(stored, observed) {
|
|
|
13386
13401
|
}
|
|
13387
13402
|
return counters.size === 0 ? undefined : Object.fromEntries(counters);
|
|
13388
13403
|
}
|
|
13404
|
+
function mergeCredits(stored, observed) {
|
|
13405
|
+
if (observed === undefined)
|
|
13406
|
+
return stored;
|
|
13407
|
+
if (stored !== undefined && observed.checkedAt < stored.checkedAt) {
|
|
13408
|
+
return stored;
|
|
13409
|
+
}
|
|
13410
|
+
return { ...observed };
|
|
13411
|
+
}
|
|
13389
13412
|
function mergeQuotaObservation(stored, observation) {
|
|
13390
13413
|
const decoded = stored === undefined ? undefined : decodeQuotaMap(stored);
|
|
13391
13414
|
if (stored !== undefined && decoded === undefined) {
|
|
@@ -13429,14 +13452,16 @@ function mergeQuotaObservation(stored, observation) {
|
|
|
13429
13452
|
const existing = entries.get(key);
|
|
13430
13453
|
entries.set(key, existing === undefined || existing.kind === "absent" ? { scope, label: pair.label, kind: "absent", checkedAt: at } : { scope, label: pair.label, kind: "retired", retiredAt: at });
|
|
13431
13454
|
}
|
|
13432
|
-
const { limits: _limits, budget: _budget, counters: _counters, ...unknownKeys } = base;
|
|
13455
|
+
const { limits: _limits, budget: _budget, counters: _counters, credits: _credits, ...unknownKeys } = base;
|
|
13433
13456
|
const budget = mergeBudget(base.budget, observation.budget, at);
|
|
13434
13457
|
const counters = mergeCounters(base.counters, observation.counters);
|
|
13458
|
+
const credits = mergeCredits(base.credits, observation.credits);
|
|
13435
13459
|
return {
|
|
13436
13460
|
...unknownKeys,
|
|
13437
13461
|
limits: [...entries.values()].sort(compareEntries),
|
|
13438
13462
|
...budget === undefined ? {} : { budget },
|
|
13439
|
-
...counters === undefined ? {} : { counters }
|
|
13463
|
+
...counters === undefined ? {} : { counters },
|
|
13464
|
+
...credits === undefined ? {} : { credits }
|
|
13440
13465
|
};
|
|
13441
13466
|
}
|
|
13442
13467
|
|
|
@@ -13512,6 +13537,13 @@ function quotaWindowParts(quota, options) {
|
|
|
13512
13537
|
const parts = windows.map(({ part }) => part);
|
|
13513
13538
|
return age === undefined ? { windows: parts } : { windows: parts, age };
|
|
13514
13539
|
}
|
|
13540
|
+
function withShortNames(windows) {
|
|
13541
|
+
const abbreviations = scopeAbbreviations(windows.filter(({ part, scope }) => part.kind === "window" && scope !== ALL_SCOPE).map(({ scope }) => scope));
|
|
13542
|
+
for (const window of windows) {
|
|
13543
|
+
window.part.short = window.part.kind === "budget" ? "cr" : window.scope === ALL_SCOPE ? window.part.name : abbreviations.get(window.scope) ?? window.scope;
|
|
13544
|
+
}
|
|
13545
|
+
return windows;
|
|
13546
|
+
}
|
|
13515
13547
|
function scopedWindowParts(quota, options) {
|
|
13516
13548
|
if (!quota)
|
|
13517
13549
|
return { windows: [] };
|
|
@@ -13525,6 +13557,7 @@ function scopedWindowParts(quota, options) {
|
|
|
13525
13557
|
part: {
|
|
13526
13558
|
kind: "window",
|
|
13527
13559
|
name: quotaWindowName(limit),
|
|
13560
|
+
short: "",
|
|
13528
13561
|
figure: percentLeft(limit.remainingPercent ?? 0),
|
|
13529
13562
|
remainingPercent,
|
|
13530
13563
|
checkedAt: limit.checkedAt,
|
|
@@ -13542,6 +13575,7 @@ function scopedWindowParts(quota, options) {
|
|
|
13542
13575
|
part: {
|
|
13543
13576
|
kind: "budget",
|
|
13544
13577
|
name: "credits",
|
|
13578
|
+
short: "",
|
|
13545
13579
|
figure,
|
|
13546
13580
|
...remainingPercent === undefined ? {} : { remainingPercent: clampPercent2(remainingPercent) },
|
|
13547
13581
|
checkedAt: budget.checkedAt,
|
|
@@ -13549,6 +13583,7 @@ function scopedWindowParts(quota, options) {
|
|
|
13549
13583
|
}
|
|
13550
13584
|
});
|
|
13551
13585
|
}
|
|
13586
|
+
withShortNames(windows);
|
|
13552
13587
|
if (windows.length > 0) {
|
|
13553
13588
|
const age = now - Math.min(...windows.map(({ part }) => part.checkedAt));
|
|
13554
13589
|
if (age > (options.staleAfterMs ?? QUOTA_STALE_AFTER_MS)) {
|
|
@@ -13629,15 +13664,14 @@ function narrowTextParts(quota, options) {
|
|
|
13629
13664
|
return grouped;
|
|
13630
13665
|
const general = windows.filter(({ part, scope }) => part.kind === "window" && scope === ALL_SCOPE);
|
|
13631
13666
|
const scoped = windows.filter(({ part, scope }) => part.kind === "window" && scope !== ALL_SCOPE);
|
|
13632
|
-
const abbreviations = scopeAbbreviations(scoped.map(({ scope }) => scope));
|
|
13633
13667
|
const budget = windows.find(({ part }) => part.kind === "budget");
|
|
13634
13668
|
const budgetLeft = budget?.spent ? 0 : budget?.part.remainingPercent;
|
|
13635
13669
|
const extras = [
|
|
13636
|
-
...scoped.map(({
|
|
13637
|
-
label:
|
|
13670
|
+
...scoped.map(({ part }) => ({
|
|
13671
|
+
label: part.short,
|
|
13638
13672
|
remaining: part.remainingPercent ?? 0
|
|
13639
13673
|
})),
|
|
13640
|
-
...budgetLeft === undefined ? [] : [{ label:
|
|
13674
|
+
...budgetLeft === undefined || budget === undefined ? [] : [{ label: budget.part.short, remaining: budgetLeft }]
|
|
13641
13675
|
];
|
|
13642
13676
|
const tightest = extras.reduce((best, item) => best === undefined || item.remaining < best.remaining ? item : best, undefined);
|
|
13643
13677
|
const pieces = general.map(({ part }) => `${part.name} ${wholePercent(part.remainingPercent ?? 0)}%`);
|
|
@@ -17774,8 +17808,12 @@ class ClaustrumScopedCustody {
|
|
|
17774
17808
|
}
|
|
17775
17809
|
}
|
|
17776
17810
|
|
|
17811
|
+
// ../../node_modules/@cortexkit/common-auth/dist/claustrum/quota-writer.js
|
|
17812
|
+
import { resolve as resolve8 } from "node:path";
|
|
17813
|
+
|
|
17777
17814
|
// ../../node_modules/@cortexkit/common-auth/dist/claustrum/roster.js
|
|
17778
17815
|
import { createHash as createHash12 } from "node:crypto";
|
|
17816
|
+
import { resolve as resolve7 } from "node:path";
|
|
17779
17817
|
|
|
17780
17818
|
// ../../node_modules/@cortexkit/common-auth/dist/claustrum/interlock.js
|
|
17781
17819
|
function matches(entry2, credentialId, accountIdentity) {
|
|
@@ -18028,11 +18066,12 @@ async function readVaultRoster(path2) {
|
|
|
18028
18066
|
var WRITE_LOCK = {
|
|
18029
18067
|
name: "claustrum-roster-write",
|
|
18030
18068
|
ttlMs: 1e4,
|
|
18031
|
-
timeoutMs: 5000
|
|
18069
|
+
timeoutMs: 5000,
|
|
18070
|
+
renew: true
|
|
18032
18071
|
};
|
|
18033
18072
|
var DISCOVERY_LEASE = { name: "claustrum-roster", ttlMs: 30000 };
|
|
18034
18073
|
async function mutateVaultRoster(path2, change, options = {}) {
|
|
18035
|
-
return withLock(path2, WRITE_LOCK, async (lock) => {
|
|
18074
|
+
return withLock(path2, { ...WRITE_LOCK, signal: options.signal }, async (lock) => {
|
|
18036
18075
|
const current = await readVaultRoster(path2);
|
|
18037
18076
|
const { next, result } = await change(current, {
|
|
18038
18077
|
assertOwned: () => lock.assertOwned()
|
|
@@ -18042,6 +18081,7 @@ async function mutateVaultRoster(path2, change, options = {}) {
|
|
|
18042
18081
|
await writeJsonAtomic(path2, next, {
|
|
18043
18082
|
beforeRename: async () => {
|
|
18044
18083
|
await options.beforePublish?.();
|
|
18084
|
+
options.signal?.throwIfAborted();
|
|
18045
18085
|
await lock.assertOwned();
|
|
18046
18086
|
}
|
|
18047
18087
|
});
|
|
@@ -18091,43 +18131,52 @@ function receiptFence(row, receipt) {
|
|
|
18091
18131
|
return "bind";
|
|
18092
18132
|
return "refuse";
|
|
18093
18133
|
}
|
|
18094
|
-
function recordVaultQuota(path2, input) {
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
const bound = fence === "bind" ? { accountIdentity: input.accountIdentity, unclaimed: true } : {};
|
|
18102
|
-
return {
|
|
18103
|
-
next: {
|
|
18104
|
-
...current,
|
|
18105
|
-
rows: current.rows.map((entry2) => entry2 === row ? { ...entry2, ...bound, quota: quota2 } : entry2)
|
|
18106
|
-
},
|
|
18107
|
-
result: true
|
|
18108
|
-
};
|
|
18134
|
+
async function recordVaultQuota(path2, input) {
|
|
18135
|
+
const { routeId, observation, ...receipt } = input;
|
|
18136
|
+
return enqueueFencedVaultQuota(path2, {
|
|
18137
|
+
routeId,
|
|
18138
|
+
observation,
|
|
18139
|
+
accountIdentity: receipt.accountIdentity,
|
|
18140
|
+
receipt
|
|
18109
18141
|
});
|
|
18110
18142
|
}
|
|
18143
|
+
async function enqueueFencedVaultQuota(path2, publication2) {
|
|
18144
|
+
if (!isQuotaObservation(publication2.observation))
|
|
18145
|
+
return false;
|
|
18146
|
+
const current = pendingVaultQuota(path2, await readVaultRoster(path2));
|
|
18147
|
+
if (!applyVaultQuota(current, publication2).kept)
|
|
18148
|
+
return false;
|
|
18149
|
+
return enqueueVaultQuota(path2, publication2);
|
|
18150
|
+
}
|
|
18111
18151
|
function recordVaultAccountQuota(path2, input) {
|
|
18112
|
-
return
|
|
18113
|
-
|
|
18114
|
-
|
|
18115
|
-
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
|
|
18121
|
-
|
|
18122
|
-
|
|
18123
|
-
|
|
18124
|
-
|
|
18152
|
+
return enqueueFencedVaultQuota(path2, input);
|
|
18153
|
+
}
|
|
18154
|
+
function applyVaultQuota(current, input) {
|
|
18155
|
+
const row = current?.rows.find((entry2) => entry2.routeId === input.routeId);
|
|
18156
|
+
const fence = !row ? "refuse" : input.receipt ? receiptFence(row, input.receipt) : row.accountIdentity !== undefined && row.accountIdentity === input.accountIdentity ? "hold" : "refuse";
|
|
18157
|
+
if (!current || !row || fence === "refuse")
|
|
18158
|
+
return { roster: current, kept: false };
|
|
18159
|
+
const quota2 = mergeQuotaObservation(row.quota, input.observation);
|
|
18160
|
+
const bound = fence === "bind" ? { accountIdentity: input.accountIdentity, unclaimed: true } : {};
|
|
18161
|
+
return {
|
|
18162
|
+
roster: {
|
|
18163
|
+
...current,
|
|
18164
|
+
rows: current.rows.map((entry2) => entry2 === row ? { ...entry2, ...bound, quota: quota2 } : entry2)
|
|
18165
|
+
},
|
|
18166
|
+
kept: true
|
|
18167
|
+
};
|
|
18168
|
+
}
|
|
18169
|
+
var pendingDiscoveries = new Map;
|
|
18170
|
+
function forgetPendingVaultDiscovery(path2) {
|
|
18171
|
+
pendingDiscoveries.delete(resolve7(path2));
|
|
18125
18172
|
}
|
|
18126
18173
|
async function refreshVaultRoster(options) {
|
|
18127
18174
|
options.signal?.throwIfAborted();
|
|
18128
18175
|
const active = async () => await options.isActive?.() ?? true;
|
|
18129
|
-
if (!await active())
|
|
18176
|
+
if (!await active()) {
|
|
18177
|
+
forgetPendingVaultDiscovery(options.path);
|
|
18130
18178
|
return;
|
|
18179
|
+
}
|
|
18131
18180
|
const lease = await acquireRefreshFileLock({
|
|
18132
18181
|
...DISCOVERY_LEASE,
|
|
18133
18182
|
path: options.path,
|
|
@@ -18140,8 +18189,18 @@ async function refreshVaultRoster(options) {
|
|
|
18140
18189
|
throw new ClaustrumConsumerError("roster-busy", "Claustrum account discovery is already in progress");
|
|
18141
18190
|
return persisted;
|
|
18142
18191
|
}
|
|
18192
|
+
const key = resolve7(options.path);
|
|
18193
|
+
let discovered;
|
|
18143
18194
|
try {
|
|
18144
|
-
const
|
|
18195
|
+
const previous = await readVaultRoster(options.path);
|
|
18196
|
+
const pending = pendingDiscoveries.get(key);
|
|
18197
|
+
discovered = pending && (pending.previousView === previous?.view || pending.inventory.view === previous?.view) ? pending : {
|
|
18198
|
+
inventory: await options.custody.discover(options.signal),
|
|
18199
|
+
previousView: previous?.view
|
|
18200
|
+
};
|
|
18201
|
+
pendingDiscoveries.delete(key);
|
|
18202
|
+
const { inventory } = discovered;
|
|
18203
|
+
options.onInventory?.(inventory);
|
|
18145
18204
|
options.signal?.throwIfAborted();
|
|
18146
18205
|
return await mutateVaultRoster(options.path, async (current) => {
|
|
18147
18206
|
if (!await active())
|
|
@@ -18152,12 +18211,238 @@ async function refreshVaultRoster(options) {
|
|
|
18152
18211
|
const next = projectVaultRoster(current, inventory, projection);
|
|
18153
18212
|
const changed = JSON.stringify(current) !== JSON.stringify(next);
|
|
18154
18213
|
return { ...changed && { next }, result: next };
|
|
18214
|
+
}, {
|
|
18215
|
+
beforePublish: async () => {
|
|
18216
|
+
options.signal?.throwIfAborted();
|
|
18217
|
+
await lease.assertOwned();
|
|
18218
|
+
}
|
|
18155
18219
|
});
|
|
18220
|
+
} catch (error) {
|
|
18221
|
+
if (error instanceof LockContentionError && discovered && !options.signal?.aborted && await active())
|
|
18222
|
+
pendingDiscoveries.set(key, discovered);
|
|
18223
|
+
throw error;
|
|
18156
18224
|
} finally {
|
|
18157
18225
|
await lease.release();
|
|
18158
18226
|
}
|
|
18159
18227
|
}
|
|
18160
18228
|
|
|
18229
|
+
// ../../node_modules/@cortexkit/common-auth/dist/claustrum/quota-writer.js
|
|
18230
|
+
var writers = new Map;
|
|
18231
|
+
var logger2 = createLogger("claustrum");
|
|
18232
|
+
var COALESCE_MS = 100;
|
|
18233
|
+
function writerFor(path2) {
|
|
18234
|
+
const key = resolve8(path2);
|
|
18235
|
+
let writer = writers.get(key);
|
|
18236
|
+
if (!writer) {
|
|
18237
|
+
writer = {
|
|
18238
|
+
path: key,
|
|
18239
|
+
pending: new Map,
|
|
18240
|
+
listeners: new Set,
|
|
18241
|
+
wake: new Set,
|
|
18242
|
+
abort: new AbortController,
|
|
18243
|
+
failures: 0,
|
|
18244
|
+
draining: false,
|
|
18245
|
+
order: 0
|
|
18246
|
+
};
|
|
18247
|
+
writers.set(key, writer);
|
|
18248
|
+
}
|
|
18249
|
+
return writer;
|
|
18250
|
+
}
|
|
18251
|
+
function retainVaultQuotaWriter(path2, listener) {
|
|
18252
|
+
const writer = writerFor(path2);
|
|
18253
|
+
writer.listeners.add(listener);
|
|
18254
|
+
let released;
|
|
18255
|
+
return () => released ??= (() => {
|
|
18256
|
+
writer.listeners.delete(listener);
|
|
18257
|
+
return writer.listeners.size ? Promise.resolve() : drainVaultQuota(path2);
|
|
18258
|
+
})();
|
|
18259
|
+
}
|
|
18260
|
+
function fields(publication2) {
|
|
18261
|
+
const result = new Map;
|
|
18262
|
+
const { observation } = publication2;
|
|
18263
|
+
const witness = JSON.stringify([
|
|
18264
|
+
publication2.routeId,
|
|
18265
|
+
publication2.receipt?.credentialId,
|
|
18266
|
+
publication2.receipt?.accountIdentitySource,
|
|
18267
|
+
publication2.receipt?.expectedAccountIdentity
|
|
18268
|
+
]);
|
|
18269
|
+
const add = (key, at, part) => result.set(`${witness}:${key}`, {
|
|
18270
|
+
at,
|
|
18271
|
+
order: 0,
|
|
18272
|
+
publication: { ...publication2, observation: part }
|
|
18273
|
+
});
|
|
18274
|
+
const keyFor = (scope, label) => JSON.stringify([scope ?? "all", label]);
|
|
18275
|
+
const read = new Set;
|
|
18276
|
+
for (const reading2 of observation.readings ?? []) {
|
|
18277
|
+
const key = keyFor(reading2.scope, reading2.label);
|
|
18278
|
+
read.add(key);
|
|
18279
|
+
add(key, observation.checkedAt, {
|
|
18280
|
+
checkedAt: observation.checkedAt,
|
|
18281
|
+
readings: [{ ...reading2 }]
|
|
18282
|
+
});
|
|
18283
|
+
}
|
|
18284
|
+
for (const pair of observation.coverage ?? []) {
|
|
18285
|
+
const key = keyFor(pair.scope, pair.label);
|
|
18286
|
+
if (!read.has(key))
|
|
18287
|
+
add(key, observation.checkedAt, {
|
|
18288
|
+
checkedAt: observation.checkedAt,
|
|
18289
|
+
coverage: [{ ...pair }]
|
|
18290
|
+
});
|
|
18291
|
+
}
|
|
18292
|
+
if (observation.budget)
|
|
18293
|
+
add("budget", observation.checkedAt, {
|
|
18294
|
+
checkedAt: observation.checkedAt,
|
|
18295
|
+
budget: { ...observation.budget }
|
|
18296
|
+
});
|
|
18297
|
+
for (const [name, counter2] of Object.entries(observation.counters ?? {})) {
|
|
18298
|
+
add(`counter:${name}`, counter2.checkedAt, {
|
|
18299
|
+
checkedAt: observation.checkedAt,
|
|
18300
|
+
counters: { [name]: { ...counter2 } }
|
|
18301
|
+
});
|
|
18302
|
+
}
|
|
18303
|
+
if (observation.credits)
|
|
18304
|
+
add("credits", observation.credits.checkedAt, {
|
|
18305
|
+
checkedAt: observation.checkedAt,
|
|
18306
|
+
credits: { ...observation.credits }
|
|
18307
|
+
});
|
|
18308
|
+
if (!result.size)
|
|
18309
|
+
add("empty", observation.checkedAt, { checkedAt: observation.checkedAt });
|
|
18310
|
+
return result;
|
|
18311
|
+
}
|
|
18312
|
+
function enqueueVaultQuota(path2, publication2) {
|
|
18313
|
+
if (!isQuotaObservation(publication2.observation))
|
|
18314
|
+
return Promise.resolve(false);
|
|
18315
|
+
const writer = writerFor(path2);
|
|
18316
|
+
const account = JSON.stringify([
|
|
18317
|
+
publication2.accountIdentity ?? null,
|
|
18318
|
+
publication2.accountIdentity === undefined ? publication2.routeId : null
|
|
18319
|
+
]);
|
|
18320
|
+
const pending = writer.pending.get(account) ?? new Map;
|
|
18321
|
+
for (const [key, field] of fields(publication2)) {
|
|
18322
|
+
const previous = pending.get(key);
|
|
18323
|
+
if (!previous || field.at >= previous.at) {
|
|
18324
|
+
field.order = ++writer.order;
|
|
18325
|
+
if (field.publication.observation.coverage)
|
|
18326
|
+
field.priorReading = previous?.publication.observation.readings ? previous.publication : previous?.priorReading;
|
|
18327
|
+
pending.set(key, field);
|
|
18328
|
+
}
|
|
18329
|
+
}
|
|
18330
|
+
if (pending.size)
|
|
18331
|
+
writer.pending.set(account, pending);
|
|
18332
|
+
for (const listener of writer.listeners)
|
|
18333
|
+
listener(publication2);
|
|
18334
|
+
schedule(writer, COALESCE_MS);
|
|
18335
|
+
return Promise.resolve(true);
|
|
18336
|
+
}
|
|
18337
|
+
function orderedFields(pending) {
|
|
18338
|
+
return [...pending.values()].flatMap((account) => [...account.values()]).sort((a, b) => a.order - b.order);
|
|
18339
|
+
}
|
|
18340
|
+
function pendingVaultQuota(path2, roster) {
|
|
18341
|
+
const writer = writers.get(resolve8(path2));
|
|
18342
|
+
if (writer) {
|
|
18343
|
+
for (const field of orderedFields(writer.pending)) {
|
|
18344
|
+
if (field.priorReading)
|
|
18345
|
+
roster = applyVaultQuota(roster, field.priorReading).roster;
|
|
18346
|
+
roster = applyVaultQuota(roster, field.publication).roster;
|
|
18347
|
+
}
|
|
18348
|
+
}
|
|
18349
|
+
return roster;
|
|
18350
|
+
}
|
|
18351
|
+
function schedule(writer, delay3) {
|
|
18352
|
+
if (writer.running || writer.timer || !writer.pending.size || writer.abort.signal.aborted)
|
|
18353
|
+
return;
|
|
18354
|
+
writer.timer = setTimeout(() => {
|
|
18355
|
+
writer.timer = undefined;
|
|
18356
|
+
flush2(writer);
|
|
18357
|
+
}, delay3);
|
|
18358
|
+
if (!writer.draining)
|
|
18359
|
+
writer.timer.unref?.();
|
|
18360
|
+
}
|
|
18361
|
+
function flush2(writer) {
|
|
18362
|
+
if (writer.running || writer.abort.signal.aborted)
|
|
18363
|
+
return;
|
|
18364
|
+
const batch = new Map([...writer.pending].map(([account, pending]) => [
|
|
18365
|
+
account,
|
|
18366
|
+
new Map(pending)
|
|
18367
|
+
]));
|
|
18368
|
+
writer.running = (async () => {
|
|
18369
|
+
try {
|
|
18370
|
+
await mutateVaultRoster(writer.path, (current) => {
|
|
18371
|
+
let next = current;
|
|
18372
|
+
for (const field of orderedFields(batch)) {
|
|
18373
|
+
if (field.priorReading)
|
|
18374
|
+
next = applyVaultQuota(next, field.priorReading).roster;
|
|
18375
|
+
next = applyVaultQuota(next, field.publication).roster;
|
|
18376
|
+
}
|
|
18377
|
+
return { ...next !== current && { next }, result: undefined };
|
|
18378
|
+
}, { signal: writer.abort.signal });
|
|
18379
|
+
for (const [account, fields2] of batch) {
|
|
18380
|
+
const pending = writer.pending.get(account);
|
|
18381
|
+
for (const [key, field] of fields2) {
|
|
18382
|
+
if (pending?.get(key) === field)
|
|
18383
|
+
pending.delete(key);
|
|
18384
|
+
}
|
|
18385
|
+
if (!pending?.size)
|
|
18386
|
+
writer.pending.delete(account);
|
|
18387
|
+
}
|
|
18388
|
+
writer.failures = 0;
|
|
18389
|
+
} catch (error) {
|
|
18390
|
+
if (!writer.abort.signal.aborted && writer.failures++ === 0) {
|
|
18391
|
+
logger2.warn("vault quota publication delayed; retrying", {
|
|
18392
|
+
error: error instanceof Error ? error.message : String(error)
|
|
18393
|
+
});
|
|
18394
|
+
}
|
|
18395
|
+
} finally {
|
|
18396
|
+
writer.running = undefined;
|
|
18397
|
+
for (const wake of writer.wake)
|
|
18398
|
+
wake();
|
|
18399
|
+
const backoff = writer.failures ? Math.min(5000, 100 * 2 ** Math.min(writer.failures, 6)) * (0.5 + Math.random()) : COALESCE_MS;
|
|
18400
|
+
schedule(writer, backoff);
|
|
18401
|
+
}
|
|
18402
|
+
})();
|
|
18403
|
+
}
|
|
18404
|
+
async function drainVaultQuota(path2, timeoutMs = 1000) {
|
|
18405
|
+
const key = resolve8(path2);
|
|
18406
|
+
const writer = writers.get(key);
|
|
18407
|
+
if (!writer)
|
|
18408
|
+
return;
|
|
18409
|
+
writer.draining = true;
|
|
18410
|
+
clearTimeout(writer.timer);
|
|
18411
|
+
writer.timer = undefined;
|
|
18412
|
+
let deadline;
|
|
18413
|
+
let wake;
|
|
18414
|
+
const drained = new Promise((done) => {
|
|
18415
|
+
wake = () => {
|
|
18416
|
+
if (!writer.pending.size || writer.abort.signal.aborted)
|
|
18417
|
+
done();
|
|
18418
|
+
};
|
|
18419
|
+
writer.wake.add(wake);
|
|
18420
|
+
wake();
|
|
18421
|
+
});
|
|
18422
|
+
try {
|
|
18423
|
+
if (writer.pending.size)
|
|
18424
|
+
flush2(writer);
|
|
18425
|
+
await Promise.race([
|
|
18426
|
+
drained,
|
|
18427
|
+
new Promise((done) => {
|
|
18428
|
+
deadline = setTimeout(done, Math.max(0, timeoutMs));
|
|
18429
|
+
})
|
|
18430
|
+
]);
|
|
18431
|
+
} finally {
|
|
18432
|
+
clearTimeout(deadline);
|
|
18433
|
+
if (wake)
|
|
18434
|
+
writer.wake.delete(wake);
|
|
18435
|
+
writer.draining = false;
|
|
18436
|
+
if (!writer.listeners.size) {
|
|
18437
|
+
writer.abort.abort();
|
|
18438
|
+
clearTimeout(writer.timer);
|
|
18439
|
+
writer.pending.clear();
|
|
18440
|
+
if (writers.get(key) === writer)
|
|
18441
|
+
writers.delete(key);
|
|
18442
|
+
}
|
|
18443
|
+
}
|
|
18444
|
+
}
|
|
18445
|
+
|
|
18161
18446
|
// ../../node_modules/@cortexkit/common-auth/dist/claustrum/consumer.js
|
|
18162
18447
|
class ClaustrumConsumer {
|
|
18163
18448
|
#options;
|
|
@@ -18175,9 +18460,13 @@ class ClaustrumConsumer {
|
|
|
18175
18460
|
#releaseInsulaWatch;
|
|
18176
18461
|
#insulaSkips = new Map;
|
|
18177
18462
|
#discoveredAt;
|
|
18463
|
+
#releaseQuotaWriter;
|
|
18178
18464
|
constructor(options) {
|
|
18179
18465
|
this.#options = options;
|
|
18180
18466
|
this.#logger = options.logger ?? createLogger("claustrum");
|
|
18467
|
+
this.#releaseQuotaWriter = retainVaultQuotaWriter(options.rosterPath, (publication2) => {
|
|
18468
|
+
this.#roster = applyVaultQuota(this.#roster, publication2).roster;
|
|
18469
|
+
});
|
|
18181
18470
|
}
|
|
18182
18471
|
#assertOpen(signal) {
|
|
18183
18472
|
this.#shutdown.signal.throwIfAborted();
|
|
@@ -18191,7 +18480,7 @@ class ClaustrumConsumer {
|
|
|
18191
18480
|
this.#shutdown.signal,
|
|
18192
18481
|
...signal ? [signal] : []
|
|
18193
18482
|
]);
|
|
18194
|
-
return new Promise((
|
|
18483
|
+
return new Promise((resolve9, reject) => {
|
|
18195
18484
|
const cleanup2 = () => {
|
|
18196
18485
|
combined.signal.removeEventListener("abort", abort);
|
|
18197
18486
|
combined.dispose();
|
|
@@ -18206,7 +18495,7 @@ class ClaustrumConsumer {
|
|
|
18206
18495
|
if (combined.signal.aborted)
|
|
18207
18496
|
reject(combined.signal.reason);
|
|
18208
18497
|
else
|
|
18209
|
-
|
|
18498
|
+
resolve9(value);
|
|
18210
18499
|
}, (error) => {
|
|
18211
18500
|
cleanup2();
|
|
18212
18501
|
reject(error);
|
|
@@ -18292,11 +18581,9 @@ class ClaustrumConsumer {
|
|
|
18292
18581
|
let discovered;
|
|
18293
18582
|
const roster = await refreshVaultRoster({
|
|
18294
18583
|
path: this.#options.rosterPath,
|
|
18295
|
-
custody
|
|
18296
|
-
|
|
18297
|
-
|
|
18298
|
-
return discovered;
|
|
18299
|
-
}
|
|
18584
|
+
custody,
|
|
18585
|
+
onInventory: (inventory) => {
|
|
18586
|
+
discovered = inventory;
|
|
18300
18587
|
},
|
|
18301
18588
|
isActive: () => this.#active(),
|
|
18302
18589
|
signal: this.#shutdown.signal,
|
|
@@ -18309,7 +18596,7 @@ class ClaustrumConsumer {
|
|
|
18309
18596
|
});
|
|
18310
18597
|
this.#assertOpen();
|
|
18311
18598
|
const changed = roster?.view !== this.#roster?.view;
|
|
18312
|
-
this.#roster = roster;
|
|
18599
|
+
this.#roster = pendingVaultQuota(this.#options.rosterPath, roster);
|
|
18313
18600
|
custody.retain(roster?.rows ?? []);
|
|
18314
18601
|
if (discovered && roster?.view !== undefined)
|
|
18315
18602
|
this.#grantReach = discovered.grantReach ? { view: roster.view, reach: discovered.grantReach } : undefined;
|
|
@@ -18406,7 +18693,7 @@ class ClaustrumConsumer {
|
|
|
18406
18693
|
return;
|
|
18407
18694
|
try {
|
|
18408
18695
|
await readClaustrumEnrollmentToken(this.#options.tokenPath);
|
|
18409
|
-
const roster = await readVaultRoster(this.#options.rosterPath);
|
|
18696
|
+
const roster = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
18410
18697
|
const row = roster?.rows.find((entry2) => entry2.routeId === routeId);
|
|
18411
18698
|
return this.#normalizeInsulaQuota(row?.accountIdentity);
|
|
18412
18699
|
} catch {
|
|
@@ -18419,7 +18706,7 @@ class ClaustrumConsumer {
|
|
|
18419
18706
|
return { miss: "unreachable" };
|
|
18420
18707
|
try {
|
|
18421
18708
|
await readClaustrumEnrollmentToken(this.#options.tokenPath);
|
|
18422
|
-
const roster = await readVaultRoster(this.#options.rosterPath);
|
|
18709
|
+
const roster = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
18423
18710
|
const account = roster?.rows.find((row) => row.routeId === routeId)?.accountIdentity;
|
|
18424
18711
|
if (!account || !this.#insula)
|
|
18425
18712
|
return { miss: "unreachable" };
|
|
@@ -18463,7 +18750,7 @@ class ClaustrumConsumer {
|
|
|
18463
18750
|
this.#insula = undefined;
|
|
18464
18751
|
throw new ClaustrumConsumerError("not-active", "Claustrum scoped custody is not active");
|
|
18465
18752
|
}
|
|
18466
|
-
const current = await readVaultRoster(this.#options.rosterPath);
|
|
18753
|
+
const current = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
18467
18754
|
this.#assertOpen(signal);
|
|
18468
18755
|
const observed = roster.rows.find((row) => row.routeId === routeId);
|
|
18469
18756
|
const configured = current?.rows.find((row) => row.routeId === routeId);
|
|
@@ -18531,17 +18818,17 @@ class ClaustrumConsumer {
|
|
|
18531
18818
|
async decline(routeId) {
|
|
18532
18819
|
this.#assertOpen();
|
|
18533
18820
|
await declineVaultRoute(this.#options.rosterPath, routeId);
|
|
18534
|
-
this.#roster = await readVaultRoster(this.#options.rosterPath);
|
|
18821
|
+
this.#roster = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
18535
18822
|
this.#custody?.retain(this.#roster?.rows ?? []);
|
|
18536
18823
|
}
|
|
18537
18824
|
async accept(routeId) {
|
|
18538
18825
|
this.#assertOpen();
|
|
18539
18826
|
await acceptVaultRoute(this.#options.rosterPath, routeId);
|
|
18540
|
-
this.#roster = await readVaultRoster(this.#options.rosterPath);
|
|
18827
|
+
this.#roster = pendingVaultQuota(this.#options.rosterPath, await readVaultRoster(this.#options.rosterPath));
|
|
18541
18828
|
}
|
|
18542
18829
|
async recordQuota(routeId, observation, attempt) {
|
|
18543
18830
|
this.#assertOpen();
|
|
18544
|
-
|
|
18831
|
+
return recordVaultQuota(this.#options.rosterPath, {
|
|
18545
18832
|
routeId,
|
|
18546
18833
|
observation,
|
|
18547
18834
|
credentialId: attempt.credentialId,
|
|
@@ -18553,20 +18840,14 @@ class ClaustrumConsumer {
|
|
|
18553
18840
|
expectedAccountIdentity: attempt.expectedAccountIdentity
|
|
18554
18841
|
}
|
|
18555
18842
|
});
|
|
18556
|
-
if (kept)
|
|
18557
|
-
this.#roster = await readVaultRoster(this.#options.rosterPath);
|
|
18558
|
-
return kept;
|
|
18559
18843
|
}
|
|
18560
18844
|
async recordAccountQuota(routeId, accountIdentity, observation) {
|
|
18561
18845
|
this.#assertOpen();
|
|
18562
|
-
|
|
18846
|
+
return recordVaultAccountQuota(this.#options.rosterPath, {
|
|
18563
18847
|
routeId,
|
|
18564
18848
|
accountIdentity,
|
|
18565
18849
|
observation
|
|
18566
18850
|
});
|
|
18567
|
-
if (kept)
|
|
18568
|
-
this.#roster = await readVaultRoster(this.#options.rosterPath);
|
|
18569
|
-
return kept;
|
|
18570
18851
|
}
|
|
18571
18852
|
close() {
|
|
18572
18853
|
if (this.#shutdown.signal.aborted)
|
|
@@ -18581,6 +18862,12 @@ class ClaustrumConsumer {
|
|
|
18581
18862
|
this.#insula = undefined;
|
|
18582
18863
|
this.#roster = undefined;
|
|
18583
18864
|
this.#grantReach = undefined;
|
|
18865
|
+
this.#releaseQuotaWriter();
|
|
18866
|
+
forgetPendingVaultDiscovery(this.#options.rosterPath);
|
|
18867
|
+
}
|
|
18868
|
+
async dispose() {
|
|
18869
|
+
this.close();
|
|
18870
|
+
await this.#releaseQuotaWriter();
|
|
18584
18871
|
}
|
|
18585
18872
|
}
|
|
18586
18873
|
|
|
@@ -18630,7 +18917,7 @@ class NativeCustodyError extends Error {
|
|
|
18630
18917
|
function createNativeCustody(options) {
|
|
18631
18918
|
const env = { ...options.env ?? process.env };
|
|
18632
18919
|
const connect = options.connect;
|
|
18633
|
-
const
|
|
18920
|
+
const logger3 = options.logger;
|
|
18634
18921
|
let closed = false;
|
|
18635
18922
|
let revoked = false;
|
|
18636
18923
|
let client;
|
|
@@ -18677,8 +18964,8 @@ function createNativeCustody(options) {
|
|
|
18677
18964
|
let stopped = false;
|
|
18678
18965
|
let inner;
|
|
18679
18966
|
let finish = () => {};
|
|
18680
|
-
const ended = new Promise((
|
|
18681
|
-
finish =
|
|
18967
|
+
const ended = new Promise((resolve9) => {
|
|
18968
|
+
finish = resolve9;
|
|
18682
18969
|
});
|
|
18683
18970
|
const failed = (error) => stopped || closed || error instanceof NativeCustodyError ? { kind: "stopped" } : classifyVaultFailure(error) === "unreachable" ? { kind: "transport_lost", error: new ClaustrumUnreachableError } : { kind: "ended" };
|
|
18684
18971
|
Promise.resolve().then(connection).then((owned) => {
|
|
@@ -18727,8 +19014,8 @@ function createNativeCustody(options) {
|
|
|
18727
19014
|
...options.setTimeout && { setTimeoutImpl: options.setTimeout },
|
|
18728
19015
|
...options.clearTimeout && { clearTimeoutImpl: options.clearTimeout },
|
|
18729
19016
|
logger: {
|
|
18730
|
-
warn: () =>
|
|
18731
|
-
debug: () =>
|
|
19017
|
+
warn: () => logger3?.warn("Native custody inventory record skipped"),
|
|
19018
|
+
debug: () => logger3?.debug("Native custody failure reported")
|
|
18732
19019
|
}
|
|
18733
19020
|
});
|
|
18734
19021
|
async function run(operation, signal) {
|
|
@@ -18852,13 +19139,13 @@ function createNativeCustody(options) {
|
|
|
18852
19139
|
}
|
|
18853
19140
|
|
|
18854
19141
|
// src/native-vault-invalidation.ts
|
|
18855
|
-
import { resolve as
|
|
19142
|
+
import { resolve as resolve9 } from "node:path";
|
|
18856
19143
|
var holders = new Set;
|
|
18857
19144
|
function watchNativeVaultAuthority(holder) {
|
|
18858
19145
|
const held = {
|
|
18859
19146
|
...holder,
|
|
18860
|
-
roster:
|
|
18861
|
-
tokenPath:
|
|
19147
|
+
roster: resolve9(holder.roster),
|
|
19148
|
+
tokenPath: resolve9(holder.tokenPath)
|
|
18862
19149
|
};
|
|
18863
19150
|
holders.add(held);
|
|
18864
19151
|
return () => {
|
|
@@ -18867,12 +19154,12 @@ function watchNativeVaultAuthority(holder) {
|
|
|
18867
19154
|
}
|
|
18868
19155
|
function retainNativeVaultRoster(path2, roster) {
|
|
18869
19156
|
for (const holder of holders)
|
|
18870
|
-
if (holder.roster ===
|
|
19157
|
+
if (holder.roster === resolve9(path2))
|
|
18871
19158
|
holder.retain(roster);
|
|
18872
19159
|
}
|
|
18873
19160
|
function closeNativeVaultAuthority(tokenPath) {
|
|
18874
19161
|
for (const holder of holders)
|
|
18875
|
-
if (holder.tokenPath ===
|
|
19162
|
+
if (holder.tokenPath === resolve9(tokenPath))
|
|
18876
19163
|
holder.close();
|
|
18877
19164
|
}
|
|
18878
19165
|
|
|
@@ -19118,12 +19405,12 @@ async function joinNativePoolWrite(paths, signals, check, onLockEvent) {
|
|
|
19118
19405
|
function pause(ms, signals) {
|
|
19119
19406
|
if (signals.some((signal) => signal.aborted))
|
|
19120
19407
|
return Promise.resolve();
|
|
19121
|
-
return new Promise((
|
|
19408
|
+
return new Promise((resolve10) => {
|
|
19122
19409
|
const wake = () => {
|
|
19123
19410
|
clearTimeout(timer);
|
|
19124
19411
|
for (const signal of signals)
|
|
19125
19412
|
signal.removeEventListener("abort", wake);
|
|
19126
|
-
|
|
19413
|
+
resolve10();
|
|
19127
19414
|
};
|
|
19128
19415
|
const timer = setTimeout(wake, ms);
|
|
19129
19416
|
for (const signal of signals)
|
|
@@ -19379,7 +19666,7 @@ function createNativeRefreshCoordinator(options) {
|
|
|
19379
19666
|
name: spec.name,
|
|
19380
19667
|
timeoutMs: POOL_LOCK_DEFAULTS.timeoutMs
|
|
19381
19668
|
});
|
|
19382
|
-
await new Promise((
|
|
19669
|
+
await new Promise((resolve10) => setTimeout(resolve10, Math.min(POOL_LOCK_DEFAULTS.retryMs, remaining)));
|
|
19383
19670
|
}
|
|
19384
19671
|
}
|
|
19385
19672
|
async function run(job, request) {
|
|
@@ -20819,7 +21106,7 @@ function createNativeUsagePublisher(channel) {
|
|
|
20819
21106
|
return {
|
|
20820
21107
|
observe,
|
|
20821
21108
|
publish(write) {
|
|
20822
|
-
observe(new Promise((
|
|
21109
|
+
observe(new Promise((resolve10) => setTimeout(resolve10, 0)).then(write));
|
|
20823
21110
|
},
|
|
20824
21111
|
async drain() {
|
|
20825
21112
|
while (pending.size)
|
|
@@ -20895,7 +21182,7 @@ class NativeQuotaObservations extends Map {
|
|
|
20895
21182
|
}
|
|
20896
21183
|
|
|
20897
21184
|
// src/native-runtime-registry.ts
|
|
20898
|
-
import { resolve as
|
|
21185
|
+
import { resolve as resolve10 } from "node:path";
|
|
20899
21186
|
var identities = new WeakMap;
|
|
20900
21187
|
var nextIdentity = 0;
|
|
20901
21188
|
function nativeRuntimeOptionIdentity(value) {
|
|
@@ -20924,14 +21211,14 @@ function nativeRuntimeStorageKey(options) {
|
|
|
20924
21211
|
"runtime",
|
|
20925
21212
|
"journal",
|
|
20926
21213
|
"roster"
|
|
20927
|
-
].map((field) =>
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
21214
|
+
].map((field) => resolve10(paths[field])),
|
|
21215
|
+
resolve10(enrollment.tokenPath),
|
|
21216
|
+
resolve10(enrollment.statePath),
|
|
21217
|
+
resolve10(connection)
|
|
20931
21218
|
]);
|
|
20932
21219
|
}
|
|
20933
21220
|
function nativeRuntimeConnectionFile(host, env) {
|
|
20934
|
-
return
|
|
21221
|
+
return resolve10(resolveClaustrumConnectionPath(host === "pi" ? env.PI_ANTHROPIC_AUTH_CLAUSTRUM_CONNECTION_FILE : undefined, host === "pi" ? {
|
|
20935
21222
|
...env,
|
|
20936
21223
|
OPENCODE_ANTHROPIC_AUTH_CLAUSTRUM_CONNECTION_FILE: undefined
|
|
20937
21224
|
} : env));
|
|
@@ -21533,8 +21820,8 @@ function mergeHeaderQuotaSnapshot(existing, incoming) {
|
|
|
21533
21820
|
// src/quota-manager.ts
|
|
21534
21821
|
var nativeSetTimeout = globalThis.setTimeout;
|
|
21535
21822
|
function pauseOnRealTimer(ms) {
|
|
21536
|
-
return new Promise((
|
|
21537
|
-
const id2 = nativeSetTimeout(
|
|
21823
|
+
return new Promise((resolve11) => {
|
|
21824
|
+
const id2 = nativeSetTimeout(resolve11, ms);
|
|
21538
21825
|
if (typeof id2 === "object" && "unref" in id2)
|
|
21539
21826
|
id2.unref();
|
|
21540
21827
|
});
|
|
@@ -22301,7 +22588,8 @@ async function publishNativeVaultRosterSeed(paths, input, options = {}) {
|
|
|
22301
22588
|
}
|
|
22302
22589
|
async function publishNativeVaultRuntimeSeed(paths, state, options = {}) {
|
|
22303
22590
|
const imported = decodeNativeRuntime(captureNativePlainData(state), paths.storageId);
|
|
22304
|
-
|
|
22591
|
+
const assertPinned = async () => {
|
|
22592
|
+
const roster = await readVaultRoster(paths.roster);
|
|
22305
22593
|
for (const [id2, entry2] of Object.entries(imported.accounts)) {
|
|
22306
22594
|
if (entry2.binding.kind !== "custody")
|
|
22307
22595
|
continue;
|
|
@@ -22310,13 +22598,13 @@ async function publishNativeVaultRuntimeSeed(paths, state, options = {}) {
|
|
|
22310
22598
|
if (!row?.accountIdentity || row.accountIdentity !== binding2.accountIdentity || row.credentialId !== binding2.credentialId && !row.aliases?.includes(binding2.credentialId))
|
|
22311
22599
|
throw new NativeRuntimeError("publication-refused");
|
|
22312
22600
|
}
|
|
22313
|
-
|
|
22314
|
-
|
|
22315
|
-
|
|
22316
|
-
|
|
22317
|
-
|
|
22318
|
-
|
|
22319
|
-
|
|
22601
|
+
};
|
|
22602
|
+
await assertPinned();
|
|
22603
|
+
await updateNativeRuntime(paths.runtime, paths.storageId, () => imported, {
|
|
22604
|
+
beforeRename: async () => {
|
|
22605
|
+
await options.assertOwned?.();
|
|
22606
|
+
await assertPinned();
|
|
22607
|
+
}
|
|
22320
22608
|
});
|
|
22321
22609
|
}
|
|
22322
22610
|
var NATIVE_VAULT_CONNECT_TIMEOUT_MS = 2000;
|
|
@@ -22363,11 +22651,6 @@ function createNativeVaultRuntime(options) {
|
|
|
22363
22651
|
onLockEvent: options.onLockEvent
|
|
22364
22652
|
});
|
|
22365
22653
|
const observeLock = nativeLockObserver(options.onLockEvent);
|
|
22366
|
-
const observeRosterLock = () => observeLock?.({
|
|
22367
|
-
type: "acquiring",
|
|
22368
|
-
name: "claustrum-roster-write",
|
|
22369
|
-
path: paths.roster
|
|
22370
|
-
});
|
|
22371
22654
|
let rosterWatch;
|
|
22372
22655
|
let rosterWatching = false;
|
|
22373
22656
|
let rosterView;
|
|
@@ -22584,46 +22867,49 @@ function createNativeVaultRuntime(options) {
|
|
|
22584
22867
|
await requireActive(signal);
|
|
22585
22868
|
if (absentOnly && !await nativeVaultFileAbsent(paths.config))
|
|
22586
22869
|
return;
|
|
22587
|
-
|
|
22588
|
-
await
|
|
22589
|
-
|
|
22590
|
-
|
|
22591
|
-
|
|
22592
|
-
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
22596
|
-
|
|
22597
|
-
|
|
22598
|
-
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
|
|
22603
|
-
|
|
22604
|
-
|
|
22605
|
-
|
|
22606
|
-
|
|
22607
|
-
|
|
22608
|
-
|
|
22609
|
-
|
|
22610
|
-
|
|
22611
|
-
return settings;
|
|
22612
|
-
if (primary) {
|
|
22613
|
-
settings.mainAccountId = primary.routeId;
|
|
22614
|
-
settings.claustrum = {
|
|
22615
|
-
primaryAccount: {
|
|
22616
|
-
credentialId: NATIVE_PRIMARY_CREDENTIAL_ID,
|
|
22617
|
-
accountId: primary.accountIdentity
|
|
22618
|
-
}
|
|
22619
|
-
};
|
|
22620
|
-
} else {
|
|
22621
|
-
delete settings.mainAccountId;
|
|
22622
|
-
delete settings.claustrum;
|
|
22870
|
+
const roster = await readVaultRoster(paths.roster);
|
|
22871
|
+
if (absentOnly && !await nativeVaultFileAbsent(paths.config))
|
|
22872
|
+
return;
|
|
22873
|
+
const primaryFor = (roster2) => roster2?.rows.find((row) => (row.credentialId === NATIVE_PRIMARY_CREDENTIAL_ID || row.aliases?.includes(NATIVE_PRIMARY_CREDENTIAL_ID)) && row.credentialType === "oauth" && !row.stale && !row.unclaimed && typeof row.accountIdentity === "string" && row.accountIdentity.length > 0);
|
|
22874
|
+
const primary = primaryFor(roster);
|
|
22875
|
+
const read = await store.readSettings();
|
|
22876
|
+
if (read.status !== "ready")
|
|
22877
|
+
throw new NativeCustodyError("invalid-state");
|
|
22878
|
+
const previous = nativeVaultPrimaryPin(read.settings);
|
|
22879
|
+
if (!absentOnly && (!primary && !previous || primary && previous?.routeId === primary.routeId && previous.credentialId === NATIVE_PRIMARY_CREDENTIAL_ID && previous.accountIdentity === primary.accountIdentity))
|
|
22880
|
+
return;
|
|
22881
|
+
const assertPrimary = async () => {
|
|
22882
|
+
await requireActive(signal);
|
|
22883
|
+
const pinned = primaryFor(await readVaultRoster(paths.roster));
|
|
22884
|
+
if (pinned?.routeId !== primary?.routeId || pinned?.accountIdentity !== primary?.accountIdentity)
|
|
22885
|
+
throw new NativeRuntimeError("publication-refused");
|
|
22886
|
+
};
|
|
22887
|
+
const writer = createNativePoolStore({
|
|
22888
|
+
paths,
|
|
22889
|
+
quota: nativeQuotaCodec,
|
|
22890
|
+
onLockEvent: options.onLockEvent,
|
|
22891
|
+
onStep: async (point) => {
|
|
22892
|
+
if (point === "before-config-write" || point === "before-state-write") {
|
|
22893
|
+
await assertPrimary();
|
|
22623
22894
|
}
|
|
22895
|
+
}
|
|
22896
|
+
});
|
|
22897
|
+
await writer.updateSettings(async (settings) => {
|
|
22898
|
+
if (absentOnly && !await nativeVaultFileAbsent(paths.config))
|
|
22624
22899
|
return settings;
|
|
22625
|
-
|
|
22626
|
-
|
|
22900
|
+
if (primary) {
|
|
22901
|
+
settings.mainAccountId = primary.routeId;
|
|
22902
|
+
settings.claustrum = {
|
|
22903
|
+
primaryAccount: {
|
|
22904
|
+
credentialId: NATIVE_PRIMARY_CREDENTIAL_ID,
|
|
22905
|
+
accountId: primary.accountIdentity
|
|
22906
|
+
}
|
|
22907
|
+
};
|
|
22908
|
+
} else {
|
|
22909
|
+
delete settings.mainAccountId;
|
|
22910
|
+
delete settings.claustrum;
|
|
22911
|
+
}
|
|
22912
|
+
return settings;
|
|
22627
22913
|
});
|
|
22628
22914
|
}
|
|
22629
22915
|
async function rowFor(roster, routeId) {
|
|
@@ -23003,56 +23289,52 @@ function createNativeVaultRuntime(options) {
|
|
|
23003
23289
|
]);
|
|
23004
23290
|
if ((versions.get(key) ?? 0) > receipt.recordVersion)
|
|
23005
23291
|
return false;
|
|
23006
|
-
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
const
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
accountIdentity,
|
|
23028
|
-
recordVersion: receipt.recordVersion
|
|
23029
|
-
}
|
|
23030
|
-
});
|
|
23031
|
-
kept = true;
|
|
23032
|
-
return current;
|
|
23033
|
-
}, {
|
|
23034
|
-
onLockEvent: options.onLockEvent,
|
|
23035
|
-
beforeRename: async () => {
|
|
23036
|
-
await requireActive();
|
|
23037
|
-
const pinned = await rowFor(roster, route.logicalId);
|
|
23038
|
-
if (!pinned || pinned.routeId !== route.routeId || pinned.accountIdentity !== receipt.assertedAccountIdentity)
|
|
23039
|
-
throw new NativeRuntimeError("publication-refused");
|
|
23040
|
-
const superseded = (versions.get(key) ?? 0) > receipt.recordVersion;
|
|
23041
|
-
if (superseded && onSuperseded === "refuse")
|
|
23042
|
-
throw new NativeRuntimeError("runtime-conflict");
|
|
23043
|
-
await lease.assertOwned();
|
|
23044
|
-
return superseded ? "skip" : "publish";
|
|
23292
|
+
const row = await rowFor(await readVaultRoster(paths.roster), route.logicalId);
|
|
23293
|
+
if (!row?.accountIdentity || row.routeId !== route.routeId || row.accountIdentity !== receipt.assertedAccountIdentity || row.credentialId !== receipt.credentialId && !row.aliases?.includes(receipt.credentialId))
|
|
23294
|
+
return false;
|
|
23295
|
+
const accountIdentity = row.accountIdentity;
|
|
23296
|
+
let kept = false;
|
|
23297
|
+
try {
|
|
23298
|
+
const outcome = await updateNativeRuntimeOptional(paths.runtime, paths.storageId, (current) => {
|
|
23299
|
+
const old = current.accounts[route.routeId];
|
|
23300
|
+
const binding2 = old?.binding;
|
|
23301
|
+
if (binding2?.kind === "custody" && binding2.credentialId === receipt.credentialId && binding2.accountIdentity === receipt.assertedAccountIdentity && binding2.recordVersion > receipt.recordVersion)
|
|
23302
|
+
throw new NativeRuntimeError("runtime-conflict");
|
|
23303
|
+
const same = binding2?.kind === "custody" && binding2.accountIdentity === receipt.assertedAccountIdentity && (binding2.credentialId === row.credentialId || row.aliases?.includes(binding2.credentialId));
|
|
23304
|
+
current.accounts[route.routeId] = change({
|
|
23305
|
+
...same ? old : {},
|
|
23306
|
+
binding: {
|
|
23307
|
+
kind: "custody",
|
|
23308
|
+
storageId: paths.storageId,
|
|
23309
|
+
routeId: route.routeId,
|
|
23310
|
+
credentialId: receipt.credentialId,
|
|
23311
|
+
accountIdentity,
|
|
23312
|
+
recordVersion: receipt.recordVersion
|
|
23045
23313
|
}
|
|
23046
23314
|
});
|
|
23047
|
-
|
|
23048
|
-
|
|
23049
|
-
}
|
|
23050
|
-
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23054
|
-
|
|
23055
|
-
|
|
23315
|
+
kept = true;
|
|
23316
|
+
return current;
|
|
23317
|
+
}, {
|
|
23318
|
+
onLockEvent: options.onLockEvent,
|
|
23319
|
+
beforeRename: async () => {
|
|
23320
|
+
await requireActive();
|
|
23321
|
+
const pinned = await rowFor(await readVaultRoster(paths.roster), route.logicalId);
|
|
23322
|
+
if (!pinned || pinned.routeId !== route.routeId || pinned.accountIdentity !== receipt.assertedAccountIdentity || pinned.credentialId !== receipt.credentialId && !pinned.aliases?.includes(receipt.credentialId))
|
|
23323
|
+
throw new NativeRuntimeError("publication-refused");
|
|
23324
|
+
const superseded = (versions.get(key) ?? 0) > receipt.recordVersion;
|
|
23325
|
+
if (superseded && onSuperseded === "refuse")
|
|
23326
|
+
throw new NativeRuntimeError("runtime-conflict");
|
|
23327
|
+
return superseded ? "skip" : "publish";
|
|
23328
|
+
}
|
|
23329
|
+
});
|
|
23330
|
+
if (outcome.status === "skipped")
|
|
23331
|
+
return false;
|
|
23332
|
+
} catch (error) {
|
|
23333
|
+
if (error instanceof NativeRuntimeError && error.code === "runtime-conflict")
|
|
23334
|
+
return false;
|
|
23335
|
+
throw error;
|
|
23336
|
+
}
|
|
23337
|
+
return kept;
|
|
23056
23338
|
}
|
|
23057
23339
|
async function fetchReading(routeId, fetchImpl, signal, read, onFailure, dispatch) {
|
|
23058
23340
|
const combined = signalFor(signal);
|
|
@@ -23136,7 +23418,7 @@ function recencyOnly(patch) {
|
|
|
23136
23418
|
return keys4.length === 1 && keys4[0] === "lastUsed" && typeof patch.lastUsed === "number";
|
|
23137
23419
|
}
|
|
23138
23420
|
function waitFor(pending, signal) {
|
|
23139
|
-
return new Promise((
|
|
23421
|
+
return new Promise((resolve11, reject) => {
|
|
23140
23422
|
const abort = () => {
|
|
23141
23423
|
cleanup2();
|
|
23142
23424
|
reject(signal.reason);
|
|
@@ -23145,7 +23427,7 @@ function waitFor(pending, signal) {
|
|
|
23145
23427
|
signal.addEventListener("abort", abort, { once: true });
|
|
23146
23428
|
pending.then((value) => {
|
|
23147
23429
|
cleanup2();
|
|
23148
|
-
signal.aborted ? reject(signal.reason) :
|
|
23430
|
+
signal.aborted ? reject(signal.reason) : resolve11(value);
|
|
23149
23431
|
}, (error) => {
|
|
23150
23432
|
cleanup2();
|
|
23151
23433
|
reject(error);
|
|
@@ -23219,7 +23501,7 @@ function leaseNativeVaultRuntime(use, close) {
|
|
|
23219
23501
|
// src/pool-paths.ts
|
|
23220
23502
|
import { createHash as createHash17 } from "node:crypto";
|
|
23221
23503
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
23222
|
-
import { basename as basename7, dirname as dirname13, join as join14, resolve as
|
|
23504
|
+
import { basename as basename7, dirname as dirname13, join as join14, resolve as resolve11 } from "node:path";
|
|
23223
23505
|
|
|
23224
23506
|
// src/sticky-routing.ts
|
|
23225
23507
|
import { createHash as createHash16, randomUUID as randomUUID14 } from "node:crypto";
|
|
@@ -23348,8 +23630,8 @@ function migrateStickyRoutingState(source2, rowIdMap) {
|
|
|
23348
23630
|
const assignment = state.assignments[String(index)];
|
|
23349
23631
|
if (!isRecord13(original) || !assignment)
|
|
23350
23632
|
throw new Error;
|
|
23351
|
-
const
|
|
23352
|
-
if (Object.keys(original).length !==
|
|
23633
|
+
const fields2 = Object.keys(assignment).filter((field) => field !== "affinityModelId" || Object.hasOwn(original, "affinityModelId"));
|
|
23634
|
+
if (Object.keys(original).length !== fields2.length || fields2.some((field) => !Object.hasOwn(original, field) || !Object.is(original[field], Reflect.get(assignment, field)))) {
|
|
23353
23635
|
throw new Error;
|
|
23354
23636
|
}
|
|
23355
23637
|
const accountId = rowIdMap.get(assignment.accountId);
|
|
@@ -23575,7 +23857,7 @@ class StickySessionRouter {
|
|
|
23575
23857
|
if (!wait || performance.now() >= deadline) {
|
|
23576
23858
|
throw new Error("Timed out acquiring sticky routing state lock");
|
|
23577
23859
|
}
|
|
23578
|
-
await new Promise((
|
|
23860
|
+
await new Promise((resolve11) => setTimeout(resolve11, STICKY_ROUTING_LOCK_POLL_MS));
|
|
23579
23861
|
}
|
|
23580
23862
|
}
|
|
23581
23863
|
recoverLocalPins() {
|
|
@@ -23941,7 +24223,7 @@ function resolveLocalRoutingDestination(host, paths, env) {
|
|
|
23941
24223
|
return (host === "opencode" ? env.OPENCODE_ANTHROPIC_AUTH_ROUTING_STATE_FILE : env.PI_ANTHROPIC_AUTH_ROUTING_STATE_FILE) || getStickyRoutingStatePath(paths.config);
|
|
23942
24224
|
}
|
|
23943
24225
|
async function canonicalPath(path2) {
|
|
23944
|
-
const absolute =
|
|
24226
|
+
const absolute = resolve11(path2);
|
|
23945
24227
|
try {
|
|
23946
24228
|
return await realpath3(absolute);
|
|
23947
24229
|
} catch (error) {
|
|
@@ -24532,7 +24814,7 @@ class PersistentRelaySession {
|
|
|
24532
24814
|
return;
|
|
24533
24815
|
if (this.connecting)
|
|
24534
24816
|
return await this.connecting;
|
|
24535
|
-
this.connecting = new Promise((
|
|
24817
|
+
this.connecting = new Promise((resolve12, reject) => {
|
|
24536
24818
|
const url = toWebSocketUrl(this.config.url, this.config.token);
|
|
24537
24819
|
const parsed = new URL(url);
|
|
24538
24820
|
parsed.searchParams.set("affinity", this.affinity);
|
|
@@ -24554,7 +24836,7 @@ class PersistentRelaySession {
|
|
|
24554
24836
|
if (message.type === "ready") {
|
|
24555
24837
|
this.timers.clearTimeout(timeout);
|
|
24556
24838
|
this.serverState = message.state;
|
|
24557
|
-
|
|
24839
|
+
resolve12();
|
|
24558
24840
|
return;
|
|
24559
24841
|
}
|
|
24560
24842
|
this.handleMessage(message);
|
|
@@ -24606,15 +24888,15 @@ class PersistentRelaySession {
|
|
|
24606
24888
|
const sentAt = perfNowMs();
|
|
24607
24889
|
let resolveDone;
|
|
24608
24890
|
let rejectDone;
|
|
24609
|
-
const done = new Promise((
|
|
24610
|
-
resolveDone =
|
|
24891
|
+
const done = new Promise((resolve12, reject) => {
|
|
24892
|
+
resolveDone = resolve12;
|
|
24611
24893
|
rejectDone = reject;
|
|
24612
24894
|
});
|
|
24613
|
-
const response = new Promise((
|
|
24895
|
+
const response = new Promise((resolve12, reject) => {
|
|
24614
24896
|
const pending = {
|
|
24615
24897
|
payload,
|
|
24616
24898
|
bodyText,
|
|
24617
|
-
resolve:
|
|
24899
|
+
resolve: resolve12,
|
|
24618
24900
|
reject,
|
|
24619
24901
|
streamDone: false,
|
|
24620
24902
|
accepted: false,
|
|
@@ -25938,7 +26220,7 @@ function createNativeAccountRuntime(options) {
|
|
|
25938
26220
|
const { mode, paths: paths2, store: store2 } = await selectedStorage();
|
|
25939
26221
|
for (let attempt = 0;attempt < 4; attempt++) {
|
|
25940
26222
|
if (attempt)
|
|
25941
|
-
await new Promise((
|
|
26223
|
+
await new Promise((resolve12) => setTimeout(resolve12, 10));
|
|
25942
26224
|
const settings = await store2.readSettings();
|
|
25943
26225
|
if (settings.status !== "ready")
|
|
25944
26226
|
throw new NativeRuntimeError("publication-refused");
|
|
@@ -28234,8 +28516,8 @@ async function runNativeCustodyActivation(options, hooks = {}) {
|
|
|
28234
28516
|
}
|
|
28235
28517
|
async function commitMode(paths, routingPath, plan, context) {
|
|
28236
28518
|
let openGate = () => {};
|
|
28237
|
-
const gate = new Promise((
|
|
28238
|
-
openGate =
|
|
28519
|
+
const gate = new Promise((resolve12) => {
|
|
28520
|
+
openGate = resolve12;
|
|
28239
28521
|
});
|
|
28240
28522
|
let leases;
|
|
28241
28523
|
let scope;
|
|
@@ -28864,7 +29146,7 @@ function readPlain(value, allowed) {
|
|
|
28864
29146
|
const prototype = Object.getPrototypeOf(value);
|
|
28865
29147
|
if (prototype !== Object.prototype && prototype !== null)
|
|
28866
29148
|
return "malformed";
|
|
28867
|
-
const
|
|
29149
|
+
const fields2 = new Map;
|
|
28868
29150
|
let unknownKey = false;
|
|
28869
29151
|
for (const key of Reflect.ownKeys(value)) {
|
|
28870
29152
|
if (typeof key !== "string")
|
|
@@ -28875,9 +29157,9 @@ function readPlain(value, allowed) {
|
|
|
28875
29157
|
if (!allowed.includes(key))
|
|
28876
29158
|
unknownKey = true;
|
|
28877
29159
|
else
|
|
28878
|
-
|
|
29160
|
+
fields2.set(key, descriptor.value);
|
|
28879
29161
|
}
|
|
28880
|
-
return unknownKey ? "unknown-key" :
|
|
29162
|
+
return unknownKey ? "unknown-key" : fields2;
|
|
28881
29163
|
}
|
|
28882
29164
|
function readArray(value) {
|
|
28883
29165
|
if (value === null || typeof value !== "object")
|
|
@@ -28931,13 +29213,13 @@ function readKillswitchEntries(value) {
|
|
|
28931
29213
|
return;
|
|
28932
29214
|
const entries = [];
|
|
28933
29215
|
for (const item of items2) {
|
|
28934
|
-
const
|
|
28935
|
-
if (!(
|
|
29216
|
+
const fields2 = readPlain(item, ENTRY_KEYS);
|
|
29217
|
+
if (!(fields2 instanceof Map))
|
|
28936
29218
|
return;
|
|
28937
|
-
const account =
|
|
28938
|
-
const fh =
|
|
28939
|
-
const sd =
|
|
28940
|
-
const scoped =
|
|
29219
|
+
const account = fields2.get("account");
|
|
29220
|
+
const fh = fields2.get("fh");
|
|
29221
|
+
const sd = fields2.get("sd");
|
|
29222
|
+
const scoped = fields2.get("scoped");
|
|
28941
29223
|
if (!isKillswitchAccount(account))
|
|
28942
29224
|
return;
|
|
28943
29225
|
if (!isDigitInteger(fh) || !isDigitInteger(sd))
|
|
@@ -29021,14 +29303,14 @@ var CONTEXT_KEYS = [
|
|
|
29021
29303
|
"signal"
|
|
29022
29304
|
];
|
|
29023
29305
|
function readContext(value) {
|
|
29024
|
-
const
|
|
29025
|
-
if (!(
|
|
29306
|
+
const fields2 = readPlain(value, CONTEXT_KEYS);
|
|
29307
|
+
if (!(fields2 instanceof Map))
|
|
29026
29308
|
return;
|
|
29027
|
-
const interactive =
|
|
29028
|
-
const custodyMode =
|
|
29029
|
-
const confirmed =
|
|
29030
|
-
const sessionId =
|
|
29031
|
-
const rawSignal =
|
|
29309
|
+
const interactive = fields2.get("interactive");
|
|
29310
|
+
const custodyMode = fields2.get("custodyMode");
|
|
29311
|
+
const confirmed = fields2.get("confirmed");
|
|
29312
|
+
const sessionId = fields2.get("sessionId");
|
|
29313
|
+
const rawSignal = fields2.get("signal");
|
|
29032
29314
|
if (typeof interactive !== "boolean")
|
|
29033
29315
|
return;
|
|
29034
29316
|
if (custodyMode !== "local" && custodyMode !== "claustrum")
|
|
@@ -29128,9 +29410,9 @@ var DISCONNECT_RESULTS = new Set([
|
|
|
29128
29410
|
"conflict"
|
|
29129
29411
|
]);
|
|
29130
29412
|
function readOutcome(action, outcome) {
|
|
29131
|
-
const
|
|
29132
|
-
const ok =
|
|
29133
|
-
const text5 =
|
|
29413
|
+
const fields2 = readPlain(outcome, ["ok", "text"]);
|
|
29414
|
+
const ok = fields2 instanceof Map ? fields2.get("ok") : undefined;
|
|
29415
|
+
const text5 = fields2 instanceof Map ? fields2.get("text") : undefined;
|
|
29134
29416
|
if (typeof ok !== "boolean" || typeof text5 !== "string")
|
|
29135
29417
|
return Object.freeze({ status: "failed", action, code: "invalid-outcome" });
|
|
29136
29418
|
return Object.freeze({ status: "executed", action, ok, text: text5 });
|
|
@@ -29173,12 +29455,12 @@ function disconnectFailureCode(error) {
|
|
|
29173
29455
|
return "execution-failed";
|
|
29174
29456
|
}
|
|
29175
29457
|
function createNativeMenuExecutor(options) {
|
|
29176
|
-
const
|
|
29177
|
-
if (!(
|
|
29458
|
+
const fields2 = readPlain(options, ["host", "dispatch", "disconnectVault"]);
|
|
29459
|
+
if (!(fields2 instanceof Map))
|
|
29178
29460
|
throw new TypeError("Native menu executor options are invalid");
|
|
29179
|
-
const host =
|
|
29180
|
-
const dispatch =
|
|
29181
|
-
const disconnectVault =
|
|
29461
|
+
const host = fields2.get("host");
|
|
29462
|
+
const dispatch = fields2.get("dispatch");
|
|
29463
|
+
const disconnectVault = fields2.get("disconnectVault");
|
|
29182
29464
|
if (!HOSTS2.has(host))
|
|
29183
29465
|
throw invalidOption2("host");
|
|
29184
29466
|
if (typeof dispatch !== "function" || utilTypes7.isProxy(dispatch))
|
|
@@ -29933,11 +30215,11 @@ async function refreshForRequest(runtime2, ready) {
|
|
|
29933
30215
|
break;
|
|
29934
30216
|
if (combined.aborted)
|
|
29935
30217
|
break;
|
|
29936
|
-
await new Promise((
|
|
30218
|
+
await new Promise((resolve12) => {
|
|
29937
30219
|
const finish = () => {
|
|
29938
30220
|
clearTimeout(pause2);
|
|
29939
30221
|
combined.removeEventListener("abort", finish);
|
|
29940
|
-
|
|
30222
|
+
resolve12();
|
|
29941
30223
|
};
|
|
29942
30224
|
const pause2 = setTimeout(finish, 25);
|
|
29943
30225
|
combined.addEventListener("abort", finish, { once: true });
|
|
@@ -29953,16 +30235,16 @@ async function refreshForRequest(runtime2, ready) {
|
|
|
29953
30235
|
function waitForRequest(pending, signal) {
|
|
29954
30236
|
if (!signal)
|
|
29955
30237
|
return pending;
|
|
29956
|
-
return new Promise((
|
|
30238
|
+
return new Promise((resolve12, reject) => {
|
|
29957
30239
|
const abort = () => reject(signal.reason);
|
|
29958
30240
|
signal.addEventListener("abort", abort, { once: true });
|
|
29959
|
-
pending.then(
|
|
30241
|
+
pending.then(resolve12, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
29960
30242
|
if (signal.aborted)
|
|
29961
30243
|
abort();
|
|
29962
30244
|
});
|
|
29963
30245
|
}
|
|
29964
30246
|
// src/native-vault-connection.ts
|
|
29965
|
-
import { dirname as dirname17, join as join16, resolve as
|
|
30247
|
+
import { dirname as dirname17, join as join16, resolve as resolve13 } from "node:path";
|
|
29966
30248
|
// ../../node_modules/@cortexkit/common-auth/dist/opencode2/integration.js
|
|
29967
30249
|
var PLACEHOLDER_PREFIX = "common-auth-placeholder";
|
|
29968
30250
|
var PLACEHOLDER_LIFETIME_MS = 365 * 24 * 60 * 60 * 1000;
|
|
@@ -29973,7 +30255,7 @@ function placeholderSecret(integrationID) {
|
|
|
29973
30255
|
import { createHash as createHash20 } from "node:crypto";
|
|
29974
30256
|
import { constants as constants4 } from "node:fs";
|
|
29975
30257
|
import { lstat as lstat9, mkdir as mkdir13, open as open10, unlink as unlink8 } from "node:fs/promises";
|
|
29976
|
-
import { dirname as dirname16, resolve as
|
|
30258
|
+
import { dirname as dirname16, resolve as resolve12 } from "node:path";
|
|
29977
30259
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
29978
30260
|
|
|
29979
30261
|
// ../../node_modules/@cortexkit/common-auth/dist/pi-slot/lock.js
|
|
@@ -30066,7 +30348,7 @@ async function acquirePiLock(authPath, onCompromised, onRenew) {
|
|
|
30066
30348
|
if (!released && lastUpdate + RENEWAL_STALE < Date.now())
|
|
30067
30349
|
compromise();
|
|
30068
30350
|
}
|
|
30069
|
-
function
|
|
30351
|
+
function schedule2(delay3 = UPDATE) {
|
|
30070
30352
|
if (released)
|
|
30071
30353
|
return;
|
|
30072
30354
|
timer = setTimeout(() => {
|
|
@@ -30080,7 +30362,7 @@ async function acquirePiLock(authPath, onCompromised, onRenew) {
|
|
|
30080
30362
|
if (errorCode2(error) === "ENOENT" || lastUpdate + RENEWAL_STALE < Date.now())
|
|
30081
30363
|
compromise();
|
|
30082
30364
|
else
|
|
30083
|
-
|
|
30365
|
+
schedule2(1000);
|
|
30084
30366
|
}
|
|
30085
30367
|
async function update() {
|
|
30086
30368
|
assertFresh();
|
|
@@ -30113,14 +30395,14 @@ async function acquirePiLock(authPath, onCompromised, onRenew) {
|
|
|
30113
30395
|
mtime = next.getTime();
|
|
30114
30396
|
lastUpdate = Date.now();
|
|
30115
30397
|
active.set(path2, { ...identity2, mtime, renewedAt: lastUpdate });
|
|
30116
|
-
|
|
30398
|
+
schedule2();
|
|
30117
30399
|
}
|
|
30118
30400
|
onRenew?.(async () => {
|
|
30119
30401
|
if (timer)
|
|
30120
30402
|
clearTimeout(timer);
|
|
30121
30403
|
await update();
|
|
30122
30404
|
});
|
|
30123
|
-
|
|
30405
|
+
schedule2();
|
|
30124
30406
|
return {
|
|
30125
30407
|
assertFresh,
|
|
30126
30408
|
async release() {
|
|
@@ -30361,8 +30643,8 @@ function createPiSlot(options, onStep, hooks) {
|
|
|
30361
30643
|
if (!provider || !options.authPath || !options.stashPath || !placeholderKey || placeholderKey.startsWith("!") || placeholderKey.includes("$") || !Number.isFinite(timeout) || timeout < 0) {
|
|
30362
30644
|
throw new PiSlotError("invalid-options");
|
|
30363
30645
|
}
|
|
30364
|
-
const authPath =
|
|
30365
|
-
const stashPath =
|
|
30646
|
+
const authPath = resolve12(options.authPath);
|
|
30647
|
+
const stashPath = resolve12(options.stashPath);
|
|
30366
30648
|
if (authPath === stashPath || stashPath === `${authPath}.lock`) {
|
|
30367
30649
|
throw new PiSlotError("invalid-options");
|
|
30368
30650
|
}
|
|
@@ -30500,7 +30782,7 @@ function createPiSlot(options, onStep, hooks) {
|
|
|
30500
30782
|
// src/native-vault-connection.ts
|
|
30501
30783
|
function nativePiAuthSlotPaths(options) {
|
|
30502
30784
|
return {
|
|
30503
|
-
authPath:
|
|
30785
|
+
authPath: resolve13(options.authPath),
|
|
30504
30786
|
stashPath: join16(dirname17(getHostClaustrumEnrollmentPaths("pi", options.env).tokenPath), "pi-auth-slot", "anthropic.json"),
|
|
30505
30787
|
provider: "anthropic",
|
|
30506
30788
|
placeholderKey: placeholderSecret("anthropic")
|
|
@@ -30523,7 +30805,7 @@ import { createHash as createHash21 } from "node:crypto";
|
|
|
30523
30805
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
30524
30806
|
import { mkdir as mkdir14, readdir as readdir3, rm as rm8, stat as stat9, writeFile as writeFile5 } from "node:fs/promises";
|
|
30525
30807
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
30526
|
-
import { join as join17, resolve as
|
|
30808
|
+
import { join as join17, resolve as resolve14 } from "node:path";
|
|
30527
30809
|
var CLAUDE_PRIME_COMMAND_NAME = "claude-prime";
|
|
30528
30810
|
var PRIME_TICK_MS = 60000;
|
|
30529
30811
|
var PRIME_DUE_OFFSET_MS = 60000;
|
|
@@ -30714,7 +30996,7 @@ function defaultMarkerDir() {
|
|
|
30714
30996
|
return join17(tmpdir6(), "opencode-anthropic-auth", "prime");
|
|
30715
30997
|
}
|
|
30716
30998
|
function primeStorageFingerprint(storagePath) {
|
|
30717
|
-
const absolutePath =
|
|
30999
|
+
const absolutePath = resolve14(storagePath);
|
|
30718
31000
|
let canonicalPath2;
|
|
30719
31001
|
try {
|
|
30720
31002
|
canonicalPath2 = realpathSync2(absolutePath);
|