agent-shim 8.15.0 → 8.17.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 +5 -2
- package/dist/cli.cjs +1406 -217
- package/dist/index.cjs +376 -46
- package/dist/index.mjs +365 -45
- package/dist/types/index.d.ts +174 -30
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -253,6 +253,7 @@ var ProviderEnvSchema = z.record(z.string().min(1), z.string()).refine((env) =>
|
|
|
253
253
|
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
|
|
254
254
|
});
|
|
255
255
|
var CODEX_EFFORTS = ["none", "low", "medium", "high"];
|
|
256
|
+
var CODEX_LOGINS = ["codex-cli", "chatgpt-sign-in"];
|
|
256
257
|
var CODEX_DEFAULT_TIER_MODELS = Object.freeze({
|
|
257
258
|
fable: "gpt-5.6-sol",
|
|
258
259
|
opus: "gpt-5.6-sol",
|
|
@@ -270,7 +271,9 @@ var CodexProviderConfigSchema = z.strictObject({
|
|
|
270
271
|
haiku: z.string().min(1).optional()
|
|
271
272
|
}).optional(),
|
|
272
273
|
/** The reasoning effort used when the request's own `output_config.effort` is not one the backend accepts. */
|
|
273
|
-
effort: z.enum(CODEX_EFFORTS).optional()
|
|
274
|
+
effort: z.enum(CODEX_EFFORTS).optional(),
|
|
275
|
+
/** Which login the upstream call is made with; see `CODEX_LOGINS`. */
|
|
276
|
+
login: z.enum(CODEX_LOGINS).optional()
|
|
274
277
|
});
|
|
275
278
|
var HttpProviderSchema = z.strictObject({
|
|
276
279
|
$schema: z.string().optional(),
|
|
@@ -2759,8 +2762,11 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2759
2762
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
2760
2763
|
}
|
|
2761
2764
|
ticks += 1;
|
|
2762
|
-
|
|
2763
|
-
|
|
2765
|
+
const listed = listFrontDoorSessions(fs12, paths.frontdoorSessionsDir);
|
|
2766
|
+
const pruned = pruneDeadFrontDoorSessions(fs12, paths.frontdoorSessionsDir, ports.isRunning);
|
|
2767
|
+
ports.observeLaunchRegistry(listed, pruned);
|
|
2768
|
+
const prunedPids = new Set(pruned);
|
|
2769
|
+
if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
|
|
2764
2770
|
idleSince ??= ports.now();
|
|
2765
2771
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
2766
2772
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
@@ -4982,7 +4988,7 @@ function frontDoorRcApiClient(port, ca, token) {
|
|
|
4982
4988
|
}
|
|
4983
4989
|
|
|
4984
4990
|
// src/frontdoor/controlApi.ts
|
|
4985
|
-
import { createORPCClient as createORPCClient2, ORPCError as
|
|
4991
|
+
import { createORPCClient as createORPCClient2, ORPCError as ORPCError3 } from "@orpc/client";
|
|
4986
4992
|
|
|
4987
4993
|
// src/checkReport.ts
|
|
4988
4994
|
import os5 from "node:os";
|
|
@@ -5332,6 +5338,7 @@ function buildLayoutPaths(root) {
|
|
|
5332
5338
|
frontdoorCaCertFile: path14.join(root, "frontdoor", "ca", "ca.pem"),
|
|
5333
5339
|
frontdoorCaKeyFile: path14.join(root, "frontdoor", "ca", "ca.key"),
|
|
5334
5340
|
frontdoorCaBundlesDir: path14.join(root, "frontdoor", "ca", "bundles"),
|
|
5341
|
+
chatgptSignInFile: path14.join(root, "codex", "chatgpt-sign-in.json"),
|
|
5335
5342
|
frontdoorStateFile: path14.join(root, "frontdoor", "state.json"),
|
|
5336
5343
|
frontdoorLockFile: path14.join(root, "frontdoor", "start.lock"),
|
|
5337
5344
|
frontdoorControlTokenFile: path14.join(root, "frontdoor", "control-token"),
|
|
@@ -6767,7 +6774,7 @@ var ProviderKindMismatchError = class extends UsageError {
|
|
|
6767
6774
|
}
|
|
6768
6775
|
};
|
|
6769
6776
|
function isEmptyCodexConfig(config) {
|
|
6770
|
-
return config === void 0 || config.defaultModel === void 0 && config.effort === void 0 && (config.models === void 0 || Object.keys(config.models).length === 0);
|
|
6777
|
+
return config === void 0 || config.defaultModel === void 0 && config.effort === void 0 && config.login === void 0 && (config.models === void 0 || Object.keys(config.models).length === 0);
|
|
6771
6778
|
}
|
|
6772
6779
|
function addProvider(paths, name, input) {
|
|
6773
6780
|
if (providerExists(paths, name)) {
|
|
@@ -8435,7 +8442,7 @@ var CheckReportJsonSchema = z14.strictObject({
|
|
|
8435
8442
|
|
|
8436
8443
|
// src/frontdoor/controlSchemas.ts
|
|
8437
8444
|
import path27 from "node:path";
|
|
8438
|
-
import { z as
|
|
8445
|
+
import { z as z19 } from "zod";
|
|
8439
8446
|
|
|
8440
8447
|
// src/claudeShim.ts
|
|
8441
8448
|
import fs8 from "node:fs";
|
|
@@ -8639,6 +8646,85 @@ function removeIdentity(paths, name) {
|
|
|
8639
8646
|
// src/doctorReport.ts
|
|
8640
8647
|
import fs10 from "node:fs";
|
|
8641
8648
|
import path26 from "node:path";
|
|
8649
|
+
|
|
8650
|
+
// src/codex/siwcStore.ts
|
|
8651
|
+
import { z as z18 } from "zod";
|
|
8652
|
+
|
|
8653
|
+
// src/codex/auth.ts
|
|
8654
|
+
import { z as z16 } from "zod";
|
|
8655
|
+
var AuthFileSchema = z16.looseObject({
|
|
8656
|
+
tokens: z16.looseObject({
|
|
8657
|
+
access_token: z16.string().optional(),
|
|
8658
|
+
refresh_token: z16.string().optional(),
|
|
8659
|
+
id_token: z16.string().optional(),
|
|
8660
|
+
account_id: z16.string().optional()
|
|
8661
|
+
}).nullish(),
|
|
8662
|
+
last_refresh: z16.string().optional()
|
|
8663
|
+
});
|
|
8664
|
+
var TokenGrantSchema = z16.looseObject({
|
|
8665
|
+
access_token: z16.string().min(1).optional(),
|
|
8666
|
+
refresh_token: z16.string().min(1).optional(),
|
|
8667
|
+
id_token: z16.string().min(1).optional(),
|
|
8668
|
+
account_id: z16.string().min(1).optional()
|
|
8669
|
+
});
|
|
8670
|
+
var CodexAuthError = class extends Error {
|
|
8671
|
+
constructor(message) {
|
|
8672
|
+
super(message);
|
|
8673
|
+
this.name = "CodexAuthError";
|
|
8674
|
+
}
|
|
8675
|
+
};
|
|
8676
|
+
|
|
8677
|
+
// src/codex/siwc.ts
|
|
8678
|
+
import { z as z17 } from "zod";
|
|
8679
|
+
var SIWC_RESOURCE = "https://api.openai.com/v1";
|
|
8680
|
+
var SIWC_RESPONSES_URL = `${SIWC_RESOURCE}/responses`;
|
|
8681
|
+
var SIWC_PLAN_SCOPE = "chatgpt.tokens.use.direct";
|
|
8682
|
+
var TokenResponseSchema = z17.looseObject({
|
|
8683
|
+
access_token: z17.string().min(1),
|
|
8684
|
+
refresh_token: z17.string().min(1).optional(),
|
|
8685
|
+
id_token: z17.string().min(1).optional(),
|
|
8686
|
+
expires_in: z17.number().positive(),
|
|
8687
|
+
scope: z17.string().optional()
|
|
8688
|
+
});
|
|
8689
|
+
var JwtHeaderSchema = z17.looseObject({ alg: z17.string(), kid: z17.string().optional() });
|
|
8690
|
+
var IdTokenClaimsSchema = z17.looseObject({
|
|
8691
|
+
iss: z17.string(),
|
|
8692
|
+
sub: z17.string().min(1),
|
|
8693
|
+
aud: z17.union([z17.string(), z17.array(z17.string())]),
|
|
8694
|
+
exp: z17.number(),
|
|
8695
|
+
nonce: z17.string().optional(),
|
|
8696
|
+
email: z17.string().optional()
|
|
8697
|
+
});
|
|
8698
|
+
var JwksSchema = z17.object({ keys: z17.array(z17.looseObject({ kid: z17.string().optional(), kty: z17.string() })) });
|
|
8699
|
+
|
|
8700
|
+
// src/codex/siwcStore.ts
|
|
8701
|
+
var SiwcGrantSchema = z18.strictObject({
|
|
8702
|
+
clientId: z18.string().min(1),
|
|
8703
|
+
sub: z18.string().min(1),
|
|
8704
|
+
email: z18.string().optional(),
|
|
8705
|
+
idToken: z18.string().min(1),
|
|
8706
|
+
accessToken: z18.string().min(1),
|
|
8707
|
+
refreshToken: z18.string().min(1),
|
|
8708
|
+
scopes: z18.array(z18.string()).readonly(),
|
|
8709
|
+
/** When the access token stops working, in milliseconds since the epoch. */
|
|
8710
|
+
expiresAt: z18.number()
|
|
8711
|
+
});
|
|
8712
|
+
var SiwcFileSchema = z18.strictObject({ registeredClientId: z18.string().min(1).optional(), grant: SiwcGrantSchema.optional() });
|
|
8713
|
+
function parseSiwcFile(raw, filePath) {
|
|
8714
|
+
let json;
|
|
8715
|
+
try {
|
|
8716
|
+
json = JSON.parse(raw);
|
|
8717
|
+
} catch {
|
|
8718
|
+
throw new CodexAuthError(`${filePath} is not valid JSON: run \`agent-shim codex login\` again`);
|
|
8719
|
+
}
|
|
8720
|
+
const parsed = SiwcFileSchema.safeParse(json);
|
|
8721
|
+
if (!parsed.success) {
|
|
8722
|
+
throw new CodexAuthError(`${filePath} is not a Sign in with ChatGPT file: run \`agent-shim codex login\` again`);
|
|
8723
|
+
}
|
|
8724
|
+
return parsed.data;
|
|
8725
|
+
}
|
|
8726
|
+
|
|
8727
|
+
// src/doctorReport.ts
|
|
8642
8728
|
var DOCTOR_SEVERITIES = ["pass", "warn", "fail"];
|
|
8643
8729
|
var DOCTOR_SECTIONS = [
|
|
8644
8730
|
"ambient-credential",
|
|
@@ -8729,7 +8815,21 @@ function cacheClause(cacheEnv, owner, block) {
|
|
|
8729
8815
|
const state = describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block.cache, nowMs: cacheEnv.now() });
|
|
8730
8816
|
return { text: `; ${formatCachedCredentialState(state)}`, unreadable: state.status === "unreadable" };
|
|
8731
8817
|
}
|
|
8732
|
-
function
|
|
8818
|
+
function signInProblem(signIn) {
|
|
8819
|
+
if (signIn.raw === void 0) {
|
|
8820
|
+
return "nobody is signed in: run `agent-shim codex login`.";
|
|
8821
|
+
}
|
|
8822
|
+
try {
|
|
8823
|
+
const grant = parseSiwcFile(signIn.raw, signIn.path).grant;
|
|
8824
|
+
if (grant === void 0) {
|
|
8825
|
+
return "nobody is signed in: run `agent-shim codex login`.";
|
|
8826
|
+
}
|
|
8827
|
+
return grant.scopes.includes(SIWC_PLAN_SCOPE) ? void 0 : "the login was not given permission to use your ChatGPT plan: run `agent-shim codex login` again and allow it.";
|
|
8828
|
+
} catch (error) {
|
|
8829
|
+
return error instanceof Error ? error.message : String(error);
|
|
8830
|
+
}
|
|
8831
|
+
}
|
|
8832
|
+
function pushProvider(push, entry, cacheEnv, signIn) {
|
|
8733
8833
|
if (entry.raw === void 0) {
|
|
8734
8834
|
push("provider", "fail", `${entry.path} is missing.`, entry.name);
|
|
8735
8835
|
return;
|
|
@@ -8756,6 +8856,12 @@ function pushProvider(push, entry, cacheEnv) {
|
|
|
8756
8856
|
if (validated2.data.env?.ENABLE_TOOL_SEARCH === void 0) {
|
|
8757
8857
|
push("provider", "warn", `${entry.name} does not set ENABLE_TOOL_SEARCH: a session on this provider loads MCP tools upfront rather than deferring them, because its base URL is the front door, which Claude Code treats as a non-first-party host. Set ENABLE_TOOL_SEARCH in the provider's env block to restore deferred loading, when the upstream backend supports the tool_reference payloads it sends.`, entry.name);
|
|
8758
8858
|
}
|
|
8859
|
+
if (signIn !== void 0 && isCodexProvider(validated2.data) && validated2.data.codex?.login === "chatgpt-sign-in") {
|
|
8860
|
+
const problem = signInProblem(signIn);
|
|
8861
|
+
if (problem !== void 0) {
|
|
8862
|
+
push("provider", "warn", `${entry.name} uses the Sign in with ChatGPT login, but ${problem}`, entry.name);
|
|
8863
|
+
}
|
|
8864
|
+
}
|
|
8759
8865
|
}
|
|
8760
8866
|
function pushLegacyName(push, params) {
|
|
8761
8867
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
@@ -8880,7 +8986,7 @@ function runDoctor(params) {
|
|
|
8880
8986
|
return poolName === void 0 ? validIdentityNames.has(selector) : poolName in pools;
|
|
8881
8987
|
};
|
|
8882
8988
|
for (const entry of params.providers) {
|
|
8883
|
-
pushProvider(push, entry, params.credentialCache);
|
|
8989
|
+
pushProvider(push, entry, params.credentialCache, params.chatgptSignIn);
|
|
8884
8990
|
}
|
|
8885
8991
|
if (params.platform !== "darwin" || params.run === void 0) {
|
|
8886
8992
|
push("keychain", "pass", "Skipped (not macOS).");
|
|
@@ -9122,6 +9228,7 @@ function collectDoctorReport(params) {
|
|
|
9122
9228
|
const report = runDoctor({
|
|
9123
9229
|
env: params.env,
|
|
9124
9230
|
credentialCache: realCredentialCacheEnv(paths),
|
|
9231
|
+
chatgptSignIn: { path: paths.chatgptSignInFile, raw: realFsPort.readFileUtf8(paths.chatgptSignInFile) },
|
|
9125
9232
|
installedClaudeVersions: realInstalledClaudeVersions(),
|
|
9126
9233
|
identities,
|
|
9127
9234
|
configProfiles,
|
|
@@ -9158,60 +9265,121 @@ function collectDoctorReport(params) {
|
|
|
9158
9265
|
}
|
|
9159
9266
|
|
|
9160
9267
|
// src/frontdoor/controlSchemas.ts
|
|
9161
|
-
var UsageListOutputSchema =
|
|
9162
|
-
var UsageWindowsInputSchema =
|
|
9163
|
-
identity:
|
|
9164
|
-
provider:
|
|
9268
|
+
var UsageListOutputSchema = z19.strictObject({ snapshots: z19.readonly(z19.array(UsageSnapshotSchema)) });
|
|
9269
|
+
var UsageWindowsInputSchema = z19.strictObject({
|
|
9270
|
+
identity: z19.string().min(1),
|
|
9271
|
+
provider: z19.string().min(1).optional()
|
|
9165
9272
|
});
|
|
9166
|
-
var EffectiveWindowSchema =
|
|
9273
|
+
var EffectiveWindowSchema = z19.strictObject({
|
|
9167
9274
|
/** True when the window's reset time has passed, so the recorded observation describes a window that no longer exists. */
|
|
9168
|
-
reset:
|
|
9275
|
+
reset: z19.boolean(),
|
|
9169
9276
|
/** The fraction used: 0 for a reset window, otherwise what was last observed, absent when none was reported. */
|
|
9170
|
-
utilization:
|
|
9277
|
+
utilization: z19.number().optional(),
|
|
9171
9278
|
/** The reset instant, for a window that has not reset yet and reported one. */
|
|
9172
|
-
resetsAtMs:
|
|
9279
|
+
resetsAtMs: z19.number().optional(),
|
|
9173
9280
|
/** The window's own status, for a window that has not reset yet. */
|
|
9174
|
-
status:
|
|
9281
|
+
status: z19.string().optional()
|
|
9175
9282
|
});
|
|
9176
|
-
var UsageWindowsOutputSchema =
|
|
9177
|
-
identity:
|
|
9178
|
-
provider:
|
|
9283
|
+
var UsageWindowsOutputSchema = z19.strictObject({
|
|
9284
|
+
identity: z19.string(),
|
|
9285
|
+
provider: z19.string(),
|
|
9179
9286
|
/** When the rate-limit state the windows come from was observed. */
|
|
9180
|
-
observedAt:
|
|
9287
|
+
observedAt: z19.iso.datetime().optional(),
|
|
9181
9288
|
fiveHour: EffectiveWindowSchema.optional(),
|
|
9182
9289
|
sevenDay: EffectiveWindowSchema.optional()
|
|
9183
9290
|
});
|
|
9184
|
-
var FrontDoorSessionStatusSchema =
|
|
9185
|
-
pid:
|
|
9186
|
-
startedAt:
|
|
9187
|
-
alive:
|
|
9291
|
+
var FrontDoorSessionStatusSchema = z19.strictObject({
|
|
9292
|
+
pid: z19.int().positive(),
|
|
9293
|
+
startedAt: z19.number(),
|
|
9294
|
+
alive: z19.boolean()
|
|
9188
9295
|
});
|
|
9189
|
-
var HeadroomSocketTargetSchema =
|
|
9190
|
-
var FrontDoorStatusOutputSchema =
|
|
9296
|
+
var HeadroomSocketTargetSchema = z19.union([z19.strictObject({ socketPath: z19.string() }), z19.strictObject({ refused: z19.string() })]);
|
|
9297
|
+
var FrontDoorStatusOutputSchema = z19.strictObject({
|
|
9191
9298
|
state: FrontDoorStateSchema,
|
|
9192
|
-
supervisorAlive:
|
|
9193
|
-
sessions:
|
|
9299
|
+
supervisorAlive: z19.boolean(),
|
|
9300
|
+
sessions: z19.readonly(z19.array(FrontDoorSessionStatusSchema)),
|
|
9194
9301
|
headroomSocket: HeadroomSocketTargetSchema.optional(),
|
|
9195
|
-
logPath:
|
|
9196
|
-
logExists:
|
|
9302
|
+
logPath: z19.string(),
|
|
9303
|
+
logExists: z19.boolean()
|
|
9197
9304
|
});
|
|
9198
|
-
var FrontDoorSessionsOutputSchema =
|
|
9199
|
-
var CheckRunInputSchema =
|
|
9200
|
-
path:
|
|
9201
|
-
identity:
|
|
9305
|
+
var FrontDoorSessionsOutputSchema = z19.strictObject({ sessions: z19.readonly(z19.array(FrontDoorSessionStatusSchema)) });
|
|
9306
|
+
var CheckRunInputSchema = z19.strictObject({
|
|
9307
|
+
path: z19.string().min(1),
|
|
9308
|
+
identity: z19.string().min(1).optional()
|
|
9202
9309
|
}).refine((input) => path27.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
9203
|
-
var DoctorFindingSchema =
|
|
9204
|
-
section:
|
|
9205
|
-
subject:
|
|
9206
|
-
severity:
|
|
9207
|
-
message:
|
|
9310
|
+
var DoctorFindingSchema = z19.strictObject({
|
|
9311
|
+
section: z19.enum(DOCTOR_SECTIONS),
|
|
9312
|
+
subject: z19.string().optional(),
|
|
9313
|
+
severity: z19.enum(DOCTOR_SEVERITIES),
|
|
9314
|
+
message: z19.string()
|
|
9208
9315
|
});
|
|
9209
|
-
var DoctorRunOutputSchema =
|
|
9316
|
+
var DoctorRunOutputSchema = z19.strictObject({
|
|
9210
9317
|
/** False exactly when any finding is a `fail`; a `warn` never fails the report on its own. */
|
|
9211
|
-
ok:
|
|
9212
|
-
findings:
|
|
9318
|
+
ok: z19.boolean(),
|
|
9319
|
+
findings: z19.readonly(z19.array(DoctorFindingSchema))
|
|
9320
|
+
});
|
|
9321
|
+
|
|
9322
|
+
// src/frontdoor/eventsApi.ts
|
|
9323
|
+
import { ORPCError as ORPCError2 } from "@orpc/client";
|
|
9324
|
+
import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
|
|
9325
|
+
|
|
9326
|
+
// src/frontdoor/eventSchemas.ts
|
|
9327
|
+
import { z as z20 } from "zod";
|
|
9328
|
+
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
9329
|
+
var LAUNCH_EVENT_SOURCE = "launch";
|
|
9330
|
+
var DoorEventSchema = z20.strictObject({
|
|
9331
|
+
source: z20.string().min(1),
|
|
9332
|
+
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
9333
|
+
sequence: z20.number().int().positive(),
|
|
9334
|
+
payload: z20.unknown()
|
|
9335
|
+
});
|
|
9336
|
+
var DoorEventSourceQuerySchema = z20.strictObject({
|
|
9337
|
+
sources: z20.array(z20.string().min(1)).min(1).optional()
|
|
9338
|
+
});
|
|
9339
|
+
var LaunchLifecycleEventSchema = z20.strictObject({
|
|
9340
|
+
kind: z20.enum(["registered", "pruned", "ended"]),
|
|
9341
|
+
pid: z20.number().int().positive(),
|
|
9342
|
+
startedAt: z20.number(),
|
|
9343
|
+
observedAt: z20.number()
|
|
9213
9344
|
});
|
|
9214
9345
|
|
|
9346
|
+
// src/frontdoor/eventsApi.ts
|
|
9347
|
+
function createEventsApiRouter(deps) {
|
|
9348
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
9349
|
+
return {
|
|
9350
|
+
events: {
|
|
9351
|
+
subscribe: authed.input(DoorEventSourceQuerySchema).output(eventIterator2(DoorEventSchema)).handler(async function* ({ input, signal }) {
|
|
9352
|
+
if (input.sources !== void 0) {
|
|
9353
|
+
const live = deps.events.sources();
|
|
9354
|
+
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
9355
|
+
if (unknown.length > 0) {
|
|
9356
|
+
throw new ORPCError2("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
|
|
9357
|
+
}
|
|
9358
|
+
}
|
|
9359
|
+
const stream = deps.events.stream(input.sources);
|
|
9360
|
+
const ended = new Promise((resolve) => {
|
|
9361
|
+
signal?.addEventListener("abort", () => {
|
|
9362
|
+
resolve();
|
|
9363
|
+
}, { once: true });
|
|
9364
|
+
});
|
|
9365
|
+
try {
|
|
9366
|
+
for (; ; ) {
|
|
9367
|
+
signal?.throwIfAborted();
|
|
9368
|
+
const next = await Promise.race([stream.next(), ended.then(() => ({ value: void 0, done: true }))]);
|
|
9369
|
+
if (next.done === true) {
|
|
9370
|
+
signal?.throwIfAborted();
|
|
9371
|
+
return;
|
|
9372
|
+
}
|
|
9373
|
+
yield withEventMeta2(next.value, { id: String(next.value.sequence) });
|
|
9374
|
+
}
|
|
9375
|
+
} finally {
|
|
9376
|
+
stream.close();
|
|
9377
|
+
}
|
|
9378
|
+
})
|
|
9379
|
+
}
|
|
9380
|
+
};
|
|
9381
|
+
}
|
|
9382
|
+
|
|
9215
9383
|
// src/frontdoor/controlApi.ts
|
|
9216
9384
|
function createControlApiRouter(deps) {
|
|
9217
9385
|
const authed = doorApiAuth(deps.expectedToken);
|
|
@@ -9221,7 +9389,7 @@ function createControlApiRouter(deps) {
|
|
|
9221
9389
|
effectiveWindow: authed.input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
|
|
9222
9390
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
9223
9391
|
if (snapshot === void 0) {
|
|
9224
|
-
throw new
|
|
9392
|
+
throw new ORPCError3("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
|
|
9225
9393
|
}
|
|
9226
9394
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
9227
9395
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -9250,7 +9418,7 @@ function createControlApiRouter(deps) {
|
|
|
9250
9418
|
};
|
|
9251
9419
|
}
|
|
9252
9420
|
function createDoorApiRouter(deps) {
|
|
9253
|
-
return { ...createRcApiRouter(deps), ...createControlApiRouter(deps) };
|
|
9421
|
+
return { ...createRcApiRouter(deps), ...createControlApiRouter(deps), ...createEventsApiRouter(deps) };
|
|
9254
9422
|
}
|
|
9255
9423
|
function createDoorApiNodeHandler(deps) {
|
|
9256
9424
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps));
|
|
@@ -9312,6 +9480,148 @@ function formatFrontDoorStatus(status, caCertPath) {
|
|
|
9312
9480
|
return lines;
|
|
9313
9481
|
}
|
|
9314
9482
|
|
|
9483
|
+
// src/frontdoor/eventHub.ts
|
|
9484
|
+
var DOOR_EVENT_BUFFER_EVENTS = 100;
|
|
9485
|
+
function createDoorEventHub() {
|
|
9486
|
+
const sequences = /* @__PURE__ */ new Map();
|
|
9487
|
+
const registered = /* @__PURE__ */ new Set();
|
|
9488
|
+
const every = /* @__PURE__ */ new Set();
|
|
9489
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
9490
|
+
const deliver = (event) => {
|
|
9491
|
+
for (const listener of every) {
|
|
9492
|
+
listener(event);
|
|
9493
|
+
}
|
|
9494
|
+
for (const listener of bySource.get(event.source) ?? []) {
|
|
9495
|
+
listener(event);
|
|
9496
|
+
}
|
|
9497
|
+
};
|
|
9498
|
+
const publish = (source, payload) => {
|
|
9499
|
+
const sequence2 = (sequences.get(source) ?? 0) + 1;
|
|
9500
|
+
sequences.set(source, sequence2);
|
|
9501
|
+
deliver({ source, sequence: sequence2, payload });
|
|
9502
|
+
};
|
|
9503
|
+
const addListener = (sources, listener) => {
|
|
9504
|
+
if (sources === void 0) {
|
|
9505
|
+
every.add(listener);
|
|
9506
|
+
return () => {
|
|
9507
|
+
every.delete(listener);
|
|
9508
|
+
};
|
|
9509
|
+
}
|
|
9510
|
+
const listenersFor = (source) => {
|
|
9511
|
+
const listeners = bySource.get(source) ?? /* @__PURE__ */ new Set();
|
|
9512
|
+
bySource.set(source, listeners);
|
|
9513
|
+
return listeners;
|
|
9514
|
+
};
|
|
9515
|
+
const detachers = sources.map((source) => {
|
|
9516
|
+
const listeners = listenersFor(source);
|
|
9517
|
+
listeners.add(listener);
|
|
9518
|
+
return () => {
|
|
9519
|
+
listeners.delete(listener);
|
|
9520
|
+
if (listeners.size === 0) {
|
|
9521
|
+
bySource.delete(source);
|
|
9522
|
+
}
|
|
9523
|
+
};
|
|
9524
|
+
});
|
|
9525
|
+
return () => {
|
|
9526
|
+
for (const detach of detachers) {
|
|
9527
|
+
detach();
|
|
9528
|
+
}
|
|
9529
|
+
};
|
|
9530
|
+
};
|
|
9531
|
+
return {
|
|
9532
|
+
publisher: (source) => {
|
|
9533
|
+
registered.add(source);
|
|
9534
|
+
return {
|
|
9535
|
+
source,
|
|
9536
|
+
publish: (payload) => {
|
|
9537
|
+
publish(source, payload);
|
|
9538
|
+
}
|
|
9539
|
+
};
|
|
9540
|
+
},
|
|
9541
|
+
subscribe: addListener,
|
|
9542
|
+
stream: (sources) => {
|
|
9543
|
+
const queue = [];
|
|
9544
|
+
let wake;
|
|
9545
|
+
let closed = false;
|
|
9546
|
+
const detach = addListener(sources, (event) => {
|
|
9547
|
+
if (queue.length >= DOOR_EVENT_BUFFER_EVENTS) {
|
|
9548
|
+
queue.shift();
|
|
9549
|
+
}
|
|
9550
|
+
queue.push(event);
|
|
9551
|
+
wake?.();
|
|
9552
|
+
});
|
|
9553
|
+
return {
|
|
9554
|
+
next: async () => {
|
|
9555
|
+
for (; ; ) {
|
|
9556
|
+
const event = queue.shift();
|
|
9557
|
+
if (event !== void 0) {
|
|
9558
|
+
return { value: event, done: false };
|
|
9559
|
+
}
|
|
9560
|
+
if (closed) {
|
|
9561
|
+
return { value: void 0, done: true };
|
|
9562
|
+
}
|
|
9563
|
+
await new Promise((resolve) => {
|
|
9564
|
+
wake = resolve;
|
|
9565
|
+
});
|
|
9566
|
+
}
|
|
9567
|
+
},
|
|
9568
|
+
close: () => {
|
|
9569
|
+
closed = true;
|
|
9570
|
+
detach();
|
|
9571
|
+
wake?.();
|
|
9572
|
+
}
|
|
9573
|
+
};
|
|
9574
|
+
},
|
|
9575
|
+
sources: () => [...registered].sort()
|
|
9576
|
+
};
|
|
9577
|
+
}
|
|
9578
|
+
function rcFanoutOnDoorHub(fanout, hub) {
|
|
9579
|
+
const publisher = hub.publisher(DOOR_EVENT_SOURCE_RC);
|
|
9580
|
+
return {
|
|
9581
|
+
publish: (event) => {
|
|
9582
|
+
fanout.publish(event);
|
|
9583
|
+
publisher.publish(event);
|
|
9584
|
+
},
|
|
9585
|
+
subscribe: (session, listener) => fanout.subscribe(session, listener)
|
|
9586
|
+
};
|
|
9587
|
+
}
|
|
9588
|
+
|
|
9589
|
+
// src/frontdoor/launchEvents.ts
|
|
9590
|
+
function createLaunchEventPublisher(hub, now) {
|
|
9591
|
+
const publisher = hub.publisher(LAUNCH_EVENT_SOURCE);
|
|
9592
|
+
let known;
|
|
9593
|
+
return {
|
|
9594
|
+
observe: (sessions, pruned) => {
|
|
9595
|
+
const previous = known;
|
|
9596
|
+
const listed = new Map(sessions.map((session) => [session.pid, session]));
|
|
9597
|
+
const prunedSet = new Set(pruned);
|
|
9598
|
+
known = new Map([...listed].filter(([pid]) => !prunedSet.has(pid)));
|
|
9599
|
+
if (previous === void 0) {
|
|
9600
|
+
return;
|
|
9601
|
+
}
|
|
9602
|
+
const emit = (kind, pid, startedAt) => {
|
|
9603
|
+
publisher.publish({ kind, pid, startedAt, observedAt: now() });
|
|
9604
|
+
};
|
|
9605
|
+
for (const pid of pruned) {
|
|
9606
|
+
const session = listed.get(pid);
|
|
9607
|
+
if (session !== void 0) {
|
|
9608
|
+
emit("pruned", pid, session.startedAt);
|
|
9609
|
+
}
|
|
9610
|
+
}
|
|
9611
|
+
for (const [pid, session] of previous) {
|
|
9612
|
+
if (!listed.has(pid) && !prunedSet.has(pid)) {
|
|
9613
|
+
emit("ended", pid, session.startedAt);
|
|
9614
|
+
}
|
|
9615
|
+
}
|
|
9616
|
+
for (const [pid, session] of listed) {
|
|
9617
|
+
if (!previous.has(pid) && !prunedSet.has(pid)) {
|
|
9618
|
+
emit("registered", pid, session.startedAt);
|
|
9619
|
+
}
|
|
9620
|
+
}
|
|
9621
|
+
}
|
|
9622
|
+
};
|
|
9623
|
+
}
|
|
9624
|
+
|
|
9315
9625
|
// src/frontdoor/rcStream.ts
|
|
9316
9626
|
var RC_STREAM_EVENT_NAME = "client_event";
|
|
9317
9627
|
var SSE_BYTE_ORDER_MARK = 65279;
|
|
@@ -11397,6 +11707,8 @@ export {
|
|
|
11397
11707
|
CredentialCacheSchema,
|
|
11398
11708
|
CredentialSchema,
|
|
11399
11709
|
CredentialSourceSchema,
|
|
11710
|
+
DOOR_EVENT_BUFFER_EVENTS,
|
|
11711
|
+
DOOR_EVENT_SOURCE_RC,
|
|
11400
11712
|
DirectoryRuleAlreadyExistsError,
|
|
11401
11713
|
DirectoryRuleMissingTargetError,
|
|
11402
11714
|
DirectoryRuleNotFoundError,
|
|
@@ -11404,6 +11716,8 @@ export {
|
|
|
11404
11716
|
DirectoryRulesSchema,
|
|
11405
11717
|
DoctorFindingSchema,
|
|
11406
11718
|
DoctorRunOutputSchema,
|
|
11719
|
+
DoorEventSchema,
|
|
11720
|
+
DoorEventSourceQuerySchema,
|
|
11407
11721
|
EXIT_FAILURE,
|
|
11408
11722
|
EXIT_USAGE,
|
|
11409
11723
|
EffectiveWindowSchema,
|
|
@@ -11423,6 +11737,8 @@ export {
|
|
|
11423
11737
|
InvalidCategoryNameError,
|
|
11424
11738
|
InvalidIdentityNameError,
|
|
11425
11739
|
InvalidProviderNameError,
|
|
11740
|
+
LAUNCH_EVENT_SOURCE,
|
|
11741
|
+
LaunchLifecycleEventSchema,
|
|
11426
11742
|
LaunchRefusedError,
|
|
11427
11743
|
LegacyProviderFileError,
|
|
11428
11744
|
PROMPT_CACHE_TTL_MS,
|
|
@@ -11486,6 +11802,9 @@ export {
|
|
|
11486
11802
|
createControlApiRouter,
|
|
11487
11803
|
createDoorApiNodeHandler,
|
|
11488
11804
|
createDoorApiRouter,
|
|
11805
|
+
createDoorEventHub,
|
|
11806
|
+
createEventsApiRouter,
|
|
11807
|
+
createLaunchEventPublisher,
|
|
11489
11808
|
createLeafCache,
|
|
11490
11809
|
createProfile,
|
|
11491
11810
|
createRcApiNodeHandler,
|
|
@@ -11544,6 +11863,7 @@ export {
|
|
|
11544
11863
|
providerExists,
|
|
11545
11864
|
rankPool,
|
|
11546
11865
|
rcEventWriteResultFromAnswer,
|
|
11866
|
+
rcFanoutOnDoorHub,
|
|
11547
11867
|
rcObserverAsPassthrough,
|
|
11548
11868
|
rcSelfHostFromEnv,
|
|
11549
11869
|
readActiveIdentity,
|