@cortexkit/opencode-openai-auth 0.11.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -26
- package/dist/index-766sfrh5.js +1 -0
- package/dist/index-8kj7sa1p.js +12 -0
- package/dist/index-8rqfbhfw.js +221 -0
- package/dist/index-b3q3j39x.js +2 -0
- package/dist/index-bmd7x5aq.js +2 -0
- package/dist/index-eqh53k8v.js +2 -0
- package/dist/{index-sdt2d2ra.js → index-hy9030jh.js} +1 -1
- package/dist/index-jyr8y8k4.js +7 -0
- package/dist/index-rv08jmd4.js +2 -0
- package/dist/index.d.ts +578 -145
- package/dist/index.js +1 -110
- package/dist/pool-lifecycle-DbDmgabd.d.ts +2430 -0
- package/dist/port-file-Do3lQIEk.d.ts +29 -0
- package/dist/protocol-BOBdkqqm.d.ts +198 -0
- package/dist/rpc/port-file.d.ts +4 -17
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +2 -2
- package/dist/rpc/protocol.js +1 -0
- package/dist/rpc/rpc-client.d.ts +5 -4
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.d.ts +2 -0
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state-D6cUKgkm.d.ts +385 -0
- package/dist/sidebar-state.d.ts +2 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/token-util-wdza526f.js +1 -0
- package/dist/{token-9823y0pc.js → token-ypk61xj0.js} +1 -1
- package/dist/tui-preferences.js +5 -2
- package/dist/tui.d.ts +9 -4
- package/dist/v2/server.d.ts +54 -0
- package/dist/v2/server.js +4 -0
- package/package.json +21 -9
- package/src/tui/entry.mjs +26 -25
- package/src/tui-compiled/raw/logger.js +24 -0
- package/src/tui-compiled/raw/rpc/protocol.js +3 -0
- package/src/tui-compiled/raw/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/raw/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/raw/selector.js +21 -0
- package/src/tui-compiled/raw/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/raw/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/raw/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/raw/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/raw/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/raw/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/raw/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/raw/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/raw/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/raw/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/raw/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/raw/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/raw/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/raw/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/raw/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/raw/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/raw/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/raw/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/raw/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/raw/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/raw/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/raw/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/raw/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/raw/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/raw/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/raw/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/raw/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/raw/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/raw/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/raw/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/raw/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/raw/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/raw/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/raw/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/raw/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/raw/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/raw/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/raw/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/raw/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/raw/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/raw/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/raw/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/raw/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/raw/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/raw/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/raw/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/raw/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/raw/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/raw/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/raw/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/raw/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/raw/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/raw/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/raw/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/raw/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/raw/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/raw/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/raw/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/raw/sidebar-state.js +960 -0
- package/src/tui-compiled/raw/tui/command-dialogs.tsx +424 -0
- package/src/tui-compiled/raw/tui-preferences.js +135 -0
- package/src/tui-compiled/raw/tui.tsx +135 -143
- package/src/tui-compiled/runtime/logger.js +24 -0
- package/src/tui-compiled/runtime/rpc/protocol.js +3 -0
- package/src/tui-compiled/runtime/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/runtime/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/runtime/selector.js +21 -0
- package/src/tui-compiled/runtime/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/runtime/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/runtime/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/runtime/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/runtime/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/runtime/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/runtime/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/runtime/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/runtime/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/runtime/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/runtime/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/runtime/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/runtime/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/runtime/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/runtime/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/runtime/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/runtime/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/runtime/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/runtime/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/runtime/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/runtime/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/runtime/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/runtime/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/runtime/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/runtime/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/runtime/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/runtime/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/runtime/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/runtime/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/runtime/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/runtime/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/runtime/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/runtime/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/runtime/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/runtime/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/runtime/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/runtime/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/runtime/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/runtime/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/runtime/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/runtime/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/runtime/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/runtime/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/runtime/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/runtime/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/runtime/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/runtime/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/runtime/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/runtime/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/runtime/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/runtime/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/runtime/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/runtime/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/runtime/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/runtime/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/runtime/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/runtime/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/runtime/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/runtime/sidebar-state.js +960 -0
- package/src/tui-compiled/runtime/tui/command-dialogs.js +378 -0
- package/src/tui-compiled/runtime/tui-preferences.js +135 -0
- package/src/tui-compiled/runtime/{tui.tsx → tui.js} +288 -316
- package/dist/index-4effjmr6.js +0 -2
- package/dist/index-9ehhb051.js +0 -2
- package/dist/index-g3hsdjh4.js +0 -2
- package/dist/index-hh52v8sb.js +0 -2
- package/dist/index-jwn4r3sw.js +0 -1
- package/dist/index-sq36b120.js +0 -211
- package/dist/internal-BTndPmW2.d.ts +0 -914
- package/dist/quota-normalize-08hpp51v.js +0 -1
- package/dist/sidebar-state-CoKYKcLn.d.ts +0 -220
- package/dist/token-util-ypgz7rge.js +0 -1
- package/src/tui-compiled/raw/core-account-paths.ts +0 -114
- package/src/tui-compiled/raw/core-custody-state.ts +0 -243
- package/src/tui-compiled/raw/logger.ts +0 -53
- package/src/tui-compiled/raw/rpc-port-file.ts +0 -177
- package/src/tui-compiled/raw/rpc-protocol.ts +0 -12
- package/src/tui-compiled/raw/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/raw/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/raw/sidebar-state.ts +0 -1659
- package/src/tui-compiled/raw/tui-command-dialogs.tsx +0 -1096
- package/src/tui-compiled/raw/tui-preferences.ts +0 -328
- package/src/tui-compiled/runtime/core-account-paths.ts +0 -114
- package/src/tui-compiled/runtime/core-custody-state.ts +0 -243
- package/src/tui-compiled/runtime/logger.ts +0 -53
- package/src/tui-compiled/runtime/rpc-port-file.ts +0 -177
- package/src/tui-compiled/runtime/rpc-protocol.ts +0 -12
- package/src/tui-compiled/runtime/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/runtime/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/runtime/sidebar-state.ts +0 -1659
- package/src/tui-compiled/runtime/tui-command-dialogs.tsx +0 -855
- package/src/tui-compiled/runtime/tui-preferences.ts +0 -328
- package/src/tui-compiled/shared/internal.ts +0 -6
- package/src/tui-compiled/shared/logger.ts +0 -264
- package/src/tui-compiled/shared/paths.ts +0 -33
- package/src/tui-compiled/shared/refresh-file-lock.ts +0 -384
- package/src/tui-compiled/shared/util/error.ts +0 -9
- package/src/tui-compiled/shared/util/open-url.ts +0 -30
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single failure value of every store operation. `committed` is present
|
|
3
|
+
* only when the operation had already written a credential to the state file
|
|
4
|
+
* before it failed (a partial rotation or refresh): it is the credential now
|
|
5
|
+
* on disk, so a caller never has to re-read the files to learn it.
|
|
6
|
+
*/
|
|
7
|
+
export class PoolOperationError extends Error {
|
|
8
|
+
operation;
|
|
9
|
+
rowId;
|
|
10
|
+
phase;
|
|
11
|
+
retryable;
|
|
12
|
+
kind;
|
|
13
|
+
committed;
|
|
14
|
+
constructor(details) {
|
|
15
|
+
super(details.message ??
|
|
16
|
+
`${details.operation} failed (${details.kind}, ${details.phase})`, details.cause === undefined ? undefined : { cause: details.cause });
|
|
17
|
+
this.name = 'PoolOperationError';
|
|
18
|
+
this.operation = details.operation;
|
|
19
|
+
this.rowId = details.rowId;
|
|
20
|
+
this.phase = details.phase;
|
|
21
|
+
this.retryable = details.retryable;
|
|
22
|
+
this.kind = details.kind;
|
|
23
|
+
this.committed = details.committed;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Thrown when a row operation or a refresh is called from inside a hook of a
|
|
28
|
+
* lock-holding operation (or from any continuation created inside one). It is
|
|
29
|
+
* thrown before any lock is taken or waited for.
|
|
30
|
+
*/
|
|
31
|
+
export class PoolReentryError extends Error {
|
|
32
|
+
operation;
|
|
33
|
+
constructor(operation) {
|
|
34
|
+
super(`${operation} was called from inside a store hook; hand it to the caller's continuation instead`);
|
|
35
|
+
this.name = 'PoolReentryError';
|
|
36
|
+
this.operation = operation;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isQuotaMap } from "./905bffc0220f43d0-map.js";
|
|
2
|
+
import { mergeQuotaObservation } from "./4f36d333d081d040-merge.js";
|
|
3
|
+
/**
|
|
4
|
+
* The quota codec the account-pool store (the `/store` subpath) takes when it
|
|
5
|
+
* is opened: `validate` checks a stored per-row quota map and `merge` applies
|
|
6
|
+
* an observation to one, so the store persists the map without interpreting
|
|
7
|
+
* it.
|
|
8
|
+
*/
|
|
9
|
+
export const quotaCodec = Object.freeze({
|
|
10
|
+
validate: isQuotaMap,
|
|
11
|
+
merge: mergeQuotaObservation,
|
|
12
|
+
});
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { readFileSync, realpathSync, statSync, watch, } from "node:fs";
|
|
2
|
+
import { readFile, stat } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
4
|
+
import { clearTimeout, setTimeout } from "node:timers";
|
|
5
|
+
function canonicalPath(file) {
|
|
6
|
+
const path = resolve(file);
|
|
7
|
+
try {
|
|
8
|
+
return realpathSync(path);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
// Resolve existing ancestors even when the preferences file is not yet present.
|
|
12
|
+
const parent = dirname(path);
|
|
13
|
+
return parent === path ? path : join(canonicalPath(parent), basename(path));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function identity(info) {
|
|
17
|
+
return info && `${info.dev}:${info.ino}:${info.mtimeMs}:${info.size}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Share one directory watcher and metadata poll per canonical path, including
|
|
21
|
+
* across bundled copies. Native events use a 150 ms debounce; missed events
|
|
22
|
+
* recover through a 1,000 ms stat probe (formerly a 100 ms full-file poll).
|
|
23
|
+
* Watching the directory preserves atomic replacement and missing-file recovery.
|
|
24
|
+
* Only changed raw text notifies; each subscriber is isolated and independently
|
|
25
|
+
* disposable. The last unsubscribe stops both the native watcher and the poll.
|
|
26
|
+
*/
|
|
27
|
+
export function watchTuiPreferences(file, onChange, options = {}) {
|
|
28
|
+
const globals = globalThis;
|
|
29
|
+
const key = Symbol.for('cortexkit.common-auth.tui-prefs.watchers.v1');
|
|
30
|
+
const registry = globals[key] ?? new Map();
|
|
31
|
+
globals[key] = registry;
|
|
32
|
+
const path = canonicalPath(file);
|
|
33
|
+
const shared = registry.get(path);
|
|
34
|
+
if (shared)
|
|
35
|
+
return shared.subscribe(onChange);
|
|
36
|
+
const name = basename(path);
|
|
37
|
+
const read = options.fs?.readFile ?? ((file) => readFile(file, 'utf8'));
|
|
38
|
+
const probe = options.fs?.stat ?? stat;
|
|
39
|
+
let timer = null;
|
|
40
|
+
let pollTimer = null;
|
|
41
|
+
let lastMetadata = null;
|
|
42
|
+
let lastSeen = null;
|
|
43
|
+
// Seed synchronously so an immediate write cannot be absorbed as the baseline.
|
|
44
|
+
// The metadata is recorded only together with contents that were read, as in
|
|
45
|
+
// the probe below: if the first read fails, the probe keeps trying.
|
|
46
|
+
try {
|
|
47
|
+
const metadata = identity((options.fs?.statSync ?? statSync)(path));
|
|
48
|
+
lastSeen = (options.fs?.readFileSync ?? ((file) => readFileSync(file, 'utf8')))(path);
|
|
49
|
+
lastMetadata = metadata;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Missing or unreadable files are picked up by the probe later.
|
|
53
|
+
}
|
|
54
|
+
let disposed = false;
|
|
55
|
+
const subscribers = new Set();
|
|
56
|
+
let checking = Promise.resolve();
|
|
57
|
+
const checkForChange = (native) => {
|
|
58
|
+
// Serialize native and poll checks so an older read cannot roll back state.
|
|
59
|
+
checking = checking.then(async () => {
|
|
60
|
+
if (disposed)
|
|
61
|
+
return;
|
|
62
|
+
const metadata = identity(await probe(path).catch(() => null));
|
|
63
|
+
if (!native && metadata === lastMetadata)
|
|
64
|
+
return;
|
|
65
|
+
// A missing file has nothing to read; remember that so the probe stays
|
|
66
|
+
// quiet until it reappears.
|
|
67
|
+
if (metadata === null) {
|
|
68
|
+
lastMetadata = null;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const text = await read(path).catch(() => null);
|
|
72
|
+
if (disposed)
|
|
73
|
+
return;
|
|
74
|
+
// Record the metadata only once its contents were read. A failed read
|
|
75
|
+
// leaves the old value, so the next probe sees a change and retries
|
|
76
|
+
// instead of skipping a file whose new contents were never observed.
|
|
77
|
+
if (text === null)
|
|
78
|
+
return;
|
|
79
|
+
lastMetadata = metadata;
|
|
80
|
+
if (text === lastSeen)
|
|
81
|
+
return;
|
|
82
|
+
lastSeen = text;
|
|
83
|
+
for (const subscriber of [...subscribers]) {
|
|
84
|
+
if (!subscribers.has(subscriber))
|
|
85
|
+
continue;
|
|
86
|
+
try {
|
|
87
|
+
subscriber.notify();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// A broken subscriber must not prevent the others from observing a change.
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return checking;
|
|
95
|
+
};
|
|
96
|
+
const scheduleCheck = () => {
|
|
97
|
+
if (disposed)
|
|
98
|
+
return;
|
|
99
|
+
if (timer)
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
timer = setTimeout(() => {
|
|
102
|
+
timer = null;
|
|
103
|
+
void checkForChange(true);
|
|
104
|
+
}, 150);
|
|
105
|
+
};
|
|
106
|
+
let watcher = null;
|
|
107
|
+
try {
|
|
108
|
+
watcher = (options.watchDirectory ?? watch)(dirname(path), (_event, filename) => {
|
|
109
|
+
const eventName = filename?.toString();
|
|
110
|
+
const isOurs = eventName === name ||
|
|
111
|
+
(eventName?.startsWith(`${name}.`) && eventName.endsWith('.tmp'));
|
|
112
|
+
if (eventName != null && !isOurs)
|
|
113
|
+
return;
|
|
114
|
+
scheduleCheck();
|
|
115
|
+
});
|
|
116
|
+
watcher.on('error', () => {
|
|
117
|
+
// Polling continues if the native watcher fails after construction.
|
|
118
|
+
watcher?.close();
|
|
119
|
+
watcher = null;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// The probe still recovers a later creation, even with no native watcher.
|
|
124
|
+
}
|
|
125
|
+
const schedulePoll = () => {
|
|
126
|
+
if (disposed || pollTimer)
|
|
127
|
+
return;
|
|
128
|
+
pollTimer = setTimeout(() => {
|
|
129
|
+
pollTimer = null;
|
|
130
|
+
if (disposed)
|
|
131
|
+
return;
|
|
132
|
+
void checkForChange(false).finally(schedulePoll);
|
|
133
|
+
}, 1_000);
|
|
134
|
+
pollTimer.unref();
|
|
135
|
+
};
|
|
136
|
+
const entry = {
|
|
137
|
+
subscribe: (notify) => {
|
|
138
|
+
const subscriber = { notify };
|
|
139
|
+
subscribers.add(subscriber);
|
|
140
|
+
return () => {
|
|
141
|
+
if (!subscribers.delete(subscriber) || subscribers.size > 0)
|
|
142
|
+
return;
|
|
143
|
+
disposed = true;
|
|
144
|
+
if (timer)
|
|
145
|
+
clearTimeout(timer);
|
|
146
|
+
if (pollTimer)
|
|
147
|
+
clearTimeout(pollTimer);
|
|
148
|
+
watcher?.close();
|
|
149
|
+
if (registry.get(path) === entry)
|
|
150
|
+
registry.delete(path);
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
registry.set(path, entry);
|
|
155
|
+
schedulePoll();
|
|
156
|
+
return entry.subscribe(onChange);
|
|
157
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PoolOperationError } from "./04a6357627de5ed0-errors.js";
|
|
2
|
+
/** A stored marker reserves the row even when the rest of its entry is invalid. */
|
|
3
|
+
export function assertNotReserved(operation, id, reservation) {
|
|
4
|
+
if (reservation !== undefined)
|
|
5
|
+
throw new PoolOperationError({
|
|
6
|
+
operation,
|
|
7
|
+
rowId: id,
|
|
8
|
+
kind: 'row-staged',
|
|
9
|
+
phase: operation === 'pull' ? 'pull' : 'before-first-write',
|
|
10
|
+
retryable: false,
|
|
11
|
+
message: `row ${id} is reserved for roster publication`,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Projection of a keyed quota map onto one request scope.
|
|
2
|
+
//
|
|
3
|
+
// The selection primitives carried from openai-auth judge an account by a
|
|
4
|
+
// short list of windows; the keyed map can hold many (scope, label) keys. The
|
|
5
|
+
// projection resolves exactly one entry per window label for the request's
|
|
6
|
+
// scope, orders the result the way the primitives expect, and carries each
|
|
7
|
+
// entry's (scope, label) so a decision names the limit it judged rather than
|
|
8
|
+
// the position it occupied.
|
|
9
|
+
import { ALL_SCOPE, } from "./905bffc0220f43d0-map.js";
|
|
10
|
+
function project(entry) {
|
|
11
|
+
if (entry.kind === 'retired') {
|
|
12
|
+
return {
|
|
13
|
+
scope: entry.scope,
|
|
14
|
+
label: entry.label,
|
|
15
|
+
kind: 'retired',
|
|
16
|
+
checkedAt: entry.retiredAt,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (entry.kind === 'absent') {
|
|
20
|
+
return {
|
|
21
|
+
scope: entry.scope,
|
|
22
|
+
label: entry.label,
|
|
23
|
+
kind: 'absent',
|
|
24
|
+
checkedAt: entry.checkedAt,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
scope: entry.scope,
|
|
29
|
+
label: entry.label,
|
|
30
|
+
kind: 'reading',
|
|
31
|
+
checkedAt: entry.checkedAt,
|
|
32
|
+
usedPercent: entry.usedPercent,
|
|
33
|
+
remainingPercent: 100 - entry.usedPercent,
|
|
34
|
+
...(entry.windowMinutes === undefined
|
|
35
|
+
? {}
|
|
36
|
+
: { windowMinutes: entry.windowMinutes }),
|
|
37
|
+
...(entry.resetsAt === undefined ? {} : { resetsAt: entry.resetsAt }),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function compareLimits(left, right) {
|
|
41
|
+
const leftKnown = left.windowMinutes !== undefined;
|
|
42
|
+
const rightKnown = right.windowMinutes !== undefined;
|
|
43
|
+
if (leftKnown !== rightKnown)
|
|
44
|
+
return leftKnown ? -1 : 1;
|
|
45
|
+
if (leftKnown && rightKnown && left.windowMinutes !== right.windowMinutes) {
|
|
46
|
+
return (right.windowMinutes ?? 0) - (left.windowMinutes ?? 0);
|
|
47
|
+
}
|
|
48
|
+
if (left.label !== right.label)
|
|
49
|
+
return left.label < right.label ? -1 : 1;
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
function projectBudget(budget) {
|
|
53
|
+
return {
|
|
54
|
+
checkedAt: budget.checkedAt,
|
|
55
|
+
reached: budget.reached,
|
|
56
|
+
...(budget.remainingPercent === undefined
|
|
57
|
+
? {}
|
|
58
|
+
: { remainingPercent: budget.remainingPercent }),
|
|
59
|
+
...(budget.resetsAt === undefined ? {} : { resetsAt: budget.resetsAt }),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolves `map` for a request in `scope` (`all` or a model family). A family
|
|
64
|
+
* request sees only its own family's keys and the `all` keys.
|
|
65
|
+
*
|
|
66
|
+
* The label decides how a family limit relates to a general one. Under the
|
|
67
|
+
* same label, the family reading replaces the `all` reading: use this only
|
|
68
|
+
* when the provider's family figure is a more specific view of the same cap.
|
|
69
|
+
* Under different labels both limits are projected and every consumer judges
|
|
70
|
+
* both, so a family cap that applies on top of a general cap must be stored
|
|
71
|
+
* under its own label; otherwise the general cap is hidden from a family
|
|
72
|
+
* request. A family tombstone or absence record says only that no
|
|
73
|
+
* family-specific limit exists, so it does not hide an `all` entry for the
|
|
74
|
+
* same label and is used only when there is none.
|
|
75
|
+
*/
|
|
76
|
+
export function projectQuota(map, scope = ALL_SCOPE) {
|
|
77
|
+
const byLabel = new Map();
|
|
78
|
+
for (const entry of map?.limits ?? []) {
|
|
79
|
+
if (entry.scope !== scope && entry.scope !== ALL_SCOPE)
|
|
80
|
+
continue;
|
|
81
|
+
const current = byLabel.get(entry.label);
|
|
82
|
+
if (current === undefined) {
|
|
83
|
+
byLabel.set(entry.label, entry);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const family = entry.scope === ALL_SCOPE ? current : entry;
|
|
87
|
+
const general = entry.scope === ALL_SCOPE ? entry : current;
|
|
88
|
+
byLabel.set(entry.label, family.kind === 'reading' ? family : general);
|
|
89
|
+
}
|
|
90
|
+
const limits = [...byLabel.values()].map(project).sort(compareLimits);
|
|
91
|
+
const readings = limits.filter((limit) => limit.kind === 'reading');
|
|
92
|
+
const stamped = readings.length > 0 ? readings : limits;
|
|
93
|
+
const checkedAt = stamped.length > 0
|
|
94
|
+
? Math.min(...stamped.map((limit) => limit.checkedAt))
|
|
95
|
+
: undefined;
|
|
96
|
+
const budget = map?.budget?.kind === 'reading' ? projectBudget(map.budget) : undefined;
|
|
97
|
+
return {
|
|
98
|
+
scope,
|
|
99
|
+
limits,
|
|
100
|
+
...(checkedAt === undefined ? {} : { checkedAt }),
|
|
101
|
+
...(budget === undefined ? {} : { budget }),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The credit budget's own exhaustion signal. Admission and the sticky
|
|
106
|
+
* routing decision to move a session off its pinned row both use it, so the
|
|
107
|
+
* two agree on what "spent" means. `reached` is the provider's
|
|
108
|
+
* verdict (the percentage is only a display value), and the check fails open
|
|
109
|
+
* on a missing, unparsable or already-passed reset.
|
|
110
|
+
*/
|
|
111
|
+
export function budgetExhaustedResetAt(quota, now) {
|
|
112
|
+
const budget = quota?.budget;
|
|
113
|
+
if (budget?.reached !== true || typeof budget.resetsAt !== 'string') {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
const resetAtMs = Date.parse(budget.resetsAt);
|
|
117
|
+
if (!Number.isFinite(resetAtMs) || resetAtMs <= now)
|
|
118
|
+
return undefined;
|
|
119
|
+
return { resetsAt: budget.resetsAt, resetAtMs };
|
|
120
|
+
}
|
|
121
|
+
/** True for a reading at or beyond its whole window. */
|
|
122
|
+
export function readsExhausted(limit) {
|
|
123
|
+
return (limit.kind === 'reading' &&
|
|
124
|
+
typeof limit.usedPercent === 'number' &&
|
|
125
|
+
Number.isFinite(limit.usedPercent) &&
|
|
126
|
+
limit.usedPercent >= 100);
|
|
127
|
+
}
|
|
128
|
+
/** The reset time of a limit when it parses and lies after `now`. */
|
|
129
|
+
export function futureResetAt(limit, now) {
|
|
130
|
+
if (typeof limit.resetsAt !== 'string')
|
|
131
|
+
return undefined;
|
|
132
|
+
const resetAtMs = Date.parse(limit.resetsAt);
|
|
133
|
+
return Number.isFinite(resetAtMs) && resetAtMs > now ? resetAtMs : undefined;
|
|
134
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { admit, exclusionFor } from "./45bf5343bbbf9add-admission.js";
|
|
2
|
+
export { DEFAULT_FORMER_MAIN_ID, nextOrderedAttempt, orderForPlacement, resolveRoutingMode, routeOrdered, } from "./9020c407ce64f672-ordered.js";
|
|
3
|
+
export { isPinValid, pendingBytesForPins } from "./c6b176708c446d6d-pins.js";
|
|
4
|
+
export { decideStickyBreak, defaultStickyStatusClass, MIN_RESET_HOURS, MIN_WEIGHT, QUOTA_STALENESS_MS, routeSticky, selectStickyCandidate, snapshotCheckedAt, sustainableWindowWeight, } from "./901e149c5a0dbbff-sticky.js";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
execFileSync as defaultExecFileSync,
|
|
3
|
+
spawn as defaultSpawn
|
|
4
|
+
} from "node:child_process";
|
|
5
|
+
export function openUrl(url, platform = process.platform, execFileSync = defaultExecFileSync, spawn = defaultSpawn) {
|
|
6
|
+
try {
|
|
7
|
+
if (platform === "win32") {
|
|
8
|
+
const command = `Start-Process '${url.replaceAll("'", "''")}'`, encodedCommand = Buffer.from(command, "utf16le").toString("base64"), child = spawn("powershell.exe", [
|
|
9
|
+
"-NoProfile",
|
|
10
|
+
"-NonInteractive",
|
|
11
|
+
"-WindowStyle",
|
|
12
|
+
"Hidden",
|
|
13
|
+
"-EncodedCommand",
|
|
14
|
+
encodedCommand
|
|
15
|
+
], { stdio: "ignore", windowsHide: !0 });
|
|
16
|
+
child.on("error", () => {});
|
|
17
|
+
child.unref();
|
|
18
|
+
return child.pid !== void 0;
|
|
19
|
+
}
|
|
20
|
+
execFileSync(platform === "darwin" ? "open" : "xdg-open", [url], {
|
|
21
|
+
stdio: "ignore",
|
|
22
|
+
timeout: 3000
|
|
23
|
+
});
|
|
24
|
+
return !0;
|
|
25
|
+
} catch {
|
|
26
|
+
return !1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { acquireRefreshFileLock } from "./e8cd4929507508d8-refresh-file-lock.js";
|
|
2
|
+
import { LockContentionError } from "./4825e03209d6ae3e-with-lock.js";
|
|
3
|
+
/**
|
|
4
|
+
* Store lock defaults: a 15 000 ms bounded wait retried every 50 ms plus
|
|
5
|
+
* jitter, and a renewed 10 000 ms lease.
|
|
6
|
+
*/
|
|
7
|
+
export const POOL_LOCK_DEFAULTS = Object.freeze({
|
|
8
|
+
ttlMs: 10_000,
|
|
9
|
+
timeoutMs: 15_000,
|
|
10
|
+
retryMs: 50,
|
|
11
|
+
renew: true,
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Takes one lock, retrying while a live holder has it until `timeoutMs` has
|
|
15
|
+
* passed on the real clock, then throws `LockContentionError`. The lease is
|
|
16
|
+
* asserted as owned once acquired, so a caller never proceeds on a lease that
|
|
17
|
+
* expired during the wait.
|
|
18
|
+
*/
|
|
19
|
+
export async function acquirePoolLock(spec, defaults, env) {
|
|
20
|
+
const emit = (type) => {
|
|
21
|
+
try {
|
|
22
|
+
const result = env.onLockEvent?.({
|
|
23
|
+
type,
|
|
24
|
+
name: spec.name,
|
|
25
|
+
path: spec.path,
|
|
26
|
+
});
|
|
27
|
+
if (result &&
|
|
28
|
+
(typeof result === 'object' || typeof result === 'function') &&
|
|
29
|
+
'then' in result &&
|
|
30
|
+
typeof result.then === 'function') {
|
|
31
|
+
void Promise.resolve(result).catch(() => { });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Lock observers must not affect acquisition or release.
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const options = { ...defaults, ...definedOnly(spec) };
|
|
39
|
+
const started = performance.now();
|
|
40
|
+
for (;;) {
|
|
41
|
+
const lock = await acquireRefreshFileLock({
|
|
42
|
+
name: spec.name,
|
|
43
|
+
path: spec.path,
|
|
44
|
+
ttlMs: options.ttlMs,
|
|
45
|
+
now: env.now,
|
|
46
|
+
renew: options.renew,
|
|
47
|
+
onContended: () => emit('contended'),
|
|
48
|
+
...(options.renewIntervalMs !== undefined
|
|
49
|
+
? { renewIntervalMs: options.renewIntervalMs }
|
|
50
|
+
: {}),
|
|
51
|
+
...(env.onLockStep
|
|
52
|
+
? {
|
|
53
|
+
onStep: (step) => env.onLockStep?.({ name: spec.name, path: spec.path }, step),
|
|
54
|
+
}
|
|
55
|
+
: {}),
|
|
56
|
+
});
|
|
57
|
+
if (lock) {
|
|
58
|
+
emit('acquired');
|
|
59
|
+
const held = {
|
|
60
|
+
name: spec.name,
|
|
61
|
+
path: spec.path,
|
|
62
|
+
assertOwned: () => lock.assertOwned(),
|
|
63
|
+
release: async () => {
|
|
64
|
+
await lock.release();
|
|
65
|
+
emit('released');
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
await held.assertOwned();
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
await held.release();
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
return held;
|
|
76
|
+
}
|
|
77
|
+
const remaining = options.timeoutMs - (performance.now() - started);
|
|
78
|
+
if (remaining <= 0) {
|
|
79
|
+
throw new LockContentionError({
|
|
80
|
+
target: spec.path,
|
|
81
|
+
name: spec.name,
|
|
82
|
+
timeoutMs: options.timeoutMs,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const jitter = Math.floor(Math.random() * (options.retryMs + 1));
|
|
86
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(options.retryMs + jitter, remaining)));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function definedOnly(spec) {
|
|
90
|
+
const out = {};
|
|
91
|
+
if (spec.ttlMs !== undefined)
|
|
92
|
+
out.ttlMs = spec.ttlMs;
|
|
93
|
+
if (spec.timeoutMs !== undefined)
|
|
94
|
+
out.timeoutMs = spec.timeoutMs;
|
|
95
|
+
if (spec.retryMs !== undefined)
|
|
96
|
+
out.retryMs = spec.retryMs;
|
|
97
|
+
if (spec.renew !== undefined)
|
|
98
|
+
out.renew = spec.renew;
|
|
99
|
+
if (spec.renewIntervalMs !== undefined)
|
|
100
|
+
out.renewIntervalMs = spec.renewIntervalMs;
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Locks taken in order and released in reverse. Every acquisition re-asserts
|
|
105
|
+
* the leases already held, because a wait is exactly when an earlier lease
|
|
106
|
+
* can expire unnoticed.
|
|
107
|
+
*/
|
|
108
|
+
export class LockStack {
|
|
109
|
+
defaults;
|
|
110
|
+
env;
|
|
111
|
+
held = [];
|
|
112
|
+
constructor(defaults, env) {
|
|
113
|
+
this.defaults = defaults;
|
|
114
|
+
this.env = env;
|
|
115
|
+
}
|
|
116
|
+
async acquire(spec) {
|
|
117
|
+
const lock = await acquirePoolLock(spec, this.defaults, this.env);
|
|
118
|
+
this.held.push(lock);
|
|
119
|
+
await this.assertAll();
|
|
120
|
+
return lock;
|
|
121
|
+
}
|
|
122
|
+
async assertAll() {
|
|
123
|
+
for (const lock of this.held)
|
|
124
|
+
await lock.assertOwned();
|
|
125
|
+
}
|
|
126
|
+
/** Releases every lock taken after `mark` (a length of `held`), newest first. */
|
|
127
|
+
async releaseTo(mark) {
|
|
128
|
+
while (this.held.length > mark) {
|
|
129
|
+
const lock = this.held.pop();
|
|
130
|
+
await lock?.release().catch(() => { });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async releaseAll() {
|
|
134
|
+
await this.releaseTo(0);
|
|
135
|
+
}
|
|
136
|
+
}
|