agent-shim 8.29.0 → 8.31.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/dist/cli.cjs +138 -8
- package/dist/index.cjs +130 -1
- package/dist/index.mjs +123 -1
- package/dist/types/index.d.ts +183 -10
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -61796,7 +61796,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
61796
61796
|
// package.json
|
|
61797
61797
|
var package_default = {
|
|
61798
61798
|
name: "agent-shim",
|
|
61799
|
-
version: "8.
|
|
61799
|
+
version: "8.31.0",
|
|
61800
61800
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
61801
61801
|
license: "MIT",
|
|
61802
61802
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -63150,6 +63150,7 @@ function createUsageStore(deps) {
|
|
|
63150
63150
|
fs20.mkdirPrivate(paths.usageSnapshotsDir);
|
|
63151
63151
|
fs20.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
63152
63152
|
`);
|
|
63153
|
+
deps.publish?.(snapshot);
|
|
63153
63154
|
return true;
|
|
63154
63155
|
};
|
|
63155
63156
|
return {
|
|
@@ -65682,6 +65683,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65682
65683
|
try {
|
|
65683
65684
|
http8 = await ports.startProviderListener(lastPort);
|
|
65684
65685
|
} catch (error62) {
|
|
65686
|
+
ports.doorHealth.listenerFailed("provider", error62 instanceof Error ? error62.message : String(error62));
|
|
65685
65687
|
return fail(`could not start the provider listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65686
65688
|
}
|
|
65687
65689
|
if (previousSticky !== void 0 && http8.port !== previousSticky) {
|
|
@@ -65694,6 +65696,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65694
65696
|
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
65695
65697
|
} catch (error62) {
|
|
65696
65698
|
await http8.close();
|
|
65699
|
+
ports.doorHealth.listenerFailed("connect", error62 instanceof Error ? error62.message : String(error62));
|
|
65697
65700
|
return fail(`could not start the CONNECT surface: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65698
65701
|
}
|
|
65699
65702
|
if (previousStickyConnect !== void 0 && connect3.port !== previousStickyConnect) {
|
|
@@ -65707,6 +65710,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65707
65710
|
} catch (error62) {
|
|
65708
65711
|
await connect3.close();
|
|
65709
65712
|
await http8.close();
|
|
65713
|
+
ports.doorHealth.listenerFailed("direct", error62 instanceof Error ? error62.message : String(error62));
|
|
65710
65714
|
return fail(`could not start the direct listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65711
65715
|
}
|
|
65712
65716
|
if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
|
|
@@ -65714,6 +65718,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65714
65718
|
}
|
|
65715
65719
|
lastDirectPort = direct.port;
|
|
65716
65720
|
writeFrontDoorState(fs20, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http8.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
65721
|
+
ports.doorHealth.generation({ providerPort: http8.port, connectPort: connect3.port, directPort: direct.port });
|
|
65717
65722
|
fs20.removeRecursive(paths.frontdoorLockFile);
|
|
65718
65723
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http8.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
65719
65724
|
let idleSince;
|
|
@@ -65726,11 +65731,13 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65726
65731
|
const listed = listFrontDoorSessions(fs20, paths.frontdoorSessionsDir);
|
|
65727
65732
|
const pruned = pruneDeadFrontDoorSessions(fs20, paths.frontdoorSessionsDir, ports.isRunning);
|
|
65728
65733
|
ports.observeLaunchRegistry(listed, pruned);
|
|
65734
|
+
ports.checkQuotaExpiry();
|
|
65729
65735
|
const prunedPids = new Set(pruned);
|
|
65730
65736
|
if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
|
|
65731
65737
|
idleSince ??= ports.now();
|
|
65732
65738
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
65733
65739
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
65740
|
+
ports.doorHealth.idleShutdown();
|
|
65734
65741
|
await direct.close();
|
|
65735
65742
|
await connect3.close();
|
|
65736
65743
|
await http8.close();
|
|
@@ -69906,6 +69913,10 @@ var CheckRunInputSchema = external_exports.strictObject({
|
|
|
69906
69913
|
path: external_exports.string().min(1),
|
|
69907
69914
|
identity: external_exports.string().min(1).optional()
|
|
69908
69915
|
}).refine((input2) => import_node_path33.default.isAbsolute(input2.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
69916
|
+
var PoolPickInputSchema = external_exports.strictObject({
|
|
69917
|
+
pool: external_exports.string().min(1),
|
|
69918
|
+
path: external_exports.string().min(1)
|
|
69919
|
+
}).refine((input2) => import_node_path33.default.isAbsolute(input2.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
69909
69920
|
var DoctorFindingSchema = external_exports.strictObject({
|
|
69910
69921
|
section: external_exports.enum(DOCTOR_SECTIONS),
|
|
69911
69922
|
subject: external_exports.string().optional(),
|
|
@@ -73906,6 +73917,9 @@ function frontDoorRcApiClient(port, ca, token) {
|
|
|
73906
73917
|
// src/frontdoor/eventSchemas.ts
|
|
73907
73918
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
73908
73919
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
73920
|
+
var USAGE_EVENT_SOURCE = "usage";
|
|
73921
|
+
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
73922
|
+
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
73909
73923
|
var DoorEventSchema = external_exports.strictObject({
|
|
73910
73924
|
source: external_exports.string().min(1),
|
|
73911
73925
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
@@ -73921,6 +73935,20 @@ var LaunchLifecycleEventSchema = external_exports.strictObject({
|
|
|
73921
73935
|
startedAt: external_exports.number(),
|
|
73922
73936
|
observedAt: external_exports.number()
|
|
73923
73937
|
});
|
|
73938
|
+
var DoorHealthEventSchema = external_exports.discriminatedUnion("kind", [
|
|
73939
|
+
external_exports.strictObject({ kind: external_exports.literal("generation"), pid: external_exports.number().int().positive(), providerPort: external_exports.number().int().positive(), connectPort: external_exports.number().int().positive(), directPort: external_exports.number().int().positive(), observedAt: external_exports.number() }),
|
|
73940
|
+
external_exports.strictObject({ kind: external_exports.literal("listenerFailed"), pid: external_exports.number().int().positive(), listener: external_exports.enum(["provider", "connect", "direct"]), message: external_exports.string(), observedAt: external_exports.number() }),
|
|
73941
|
+
external_exports.strictObject({ kind: external_exports.literal("idleShutdown"), pid: external_exports.number().int().positive(), observedAt: external_exports.number() })
|
|
73942
|
+
]);
|
|
73943
|
+
var QuotaExpiringEventSchema = external_exports.strictObject({
|
|
73944
|
+
identity: external_exports.string().min(1),
|
|
73945
|
+
provider: external_exports.string().min(1),
|
|
73946
|
+
window: external_exports.enum(["fiveHour", "sevenDay"]),
|
|
73947
|
+
/** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
|
|
73948
|
+
utilization: external_exports.number().min(0).max(1),
|
|
73949
|
+
resetsAt: external_exports.iso.datetime(),
|
|
73950
|
+
observedAt: external_exports.number()
|
|
73951
|
+
});
|
|
73924
73952
|
|
|
73925
73953
|
// src/frontdoor/eventsApi.ts
|
|
73926
73954
|
var EVENTS_API_TAG = "events";
|
|
@@ -73965,6 +73993,7 @@ var USAGE_API_TAG = "usage";
|
|
|
73965
73993
|
var FRONTDOOR_API_TAG = "frontdoor";
|
|
73966
73994
|
var CHECK_API_TAG = "check";
|
|
73967
73995
|
var DOCTOR_API_TAG = "doctor";
|
|
73996
|
+
var POOL_API_TAG = "pool";
|
|
73968
73997
|
function createControlApiRouter(deps) {
|
|
73969
73998
|
const authed = doorApiAuth(deps.expectedToken);
|
|
73970
73999
|
return {
|
|
@@ -74008,6 +74037,18 @@ function createControlApiRouter(deps) {
|
|
|
74008
74037
|
},
|
|
74009
74038
|
doctor: {
|
|
74010
74039
|
run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
74040
|
+
},
|
|
74041
|
+
pool: {
|
|
74042
|
+
pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input: input2 }) => {
|
|
74043
|
+
const report = deps.poolPick(input2.pool, input2.path);
|
|
74044
|
+
if (report === void 0) {
|
|
74045
|
+
const live = deps.poolNames();
|
|
74046
|
+
throw new ORPCError("NOT_FOUND", {
|
|
74047
|
+
message: live.length === 0 ? `no pools are configured, so none is named ${input2.pool}` : `no pool is named ${input2.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
|
|
74048
|
+
});
|
|
74049
|
+
}
|
|
74050
|
+
return report;
|
|
74051
|
+
})
|
|
74011
74052
|
}
|
|
74012
74053
|
};
|
|
74013
74054
|
}
|
|
@@ -74018,6 +74059,22 @@ function createDoorApiNodeHandler(deps) {
|
|
|
74018
74059
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
74019
74060
|
}
|
|
74020
74061
|
|
|
74062
|
+
// src/frontdoor/doorHealthEvents.ts
|
|
74063
|
+
function createDoorHealthPublisher(hub, now, pid) {
|
|
74064
|
+
const publisher = hub.publisher(DOOR_HEALTH_EVENT_SOURCE);
|
|
74065
|
+
return {
|
|
74066
|
+
generation: (ports) => {
|
|
74067
|
+
publisher.publish({ kind: "generation", pid, providerPort: ports.providerPort, connectPort: ports.connectPort, directPort: ports.directPort, observedAt: now() });
|
|
74068
|
+
},
|
|
74069
|
+
listenerFailed: (listener, message) => {
|
|
74070
|
+
publisher.publish({ kind: "listenerFailed", pid, listener, message, observedAt: now() });
|
|
74071
|
+
},
|
|
74072
|
+
idleShutdown: () => {
|
|
74073
|
+
publisher.publish({ kind: "idleShutdown", pid, observedAt: now() });
|
|
74074
|
+
}
|
|
74075
|
+
};
|
|
74076
|
+
}
|
|
74077
|
+
|
|
74021
74078
|
// src/frontdoor/eventHub.ts
|
|
74022
74079
|
var DOOR_EVENT_BUFFER_EVENTS = 100;
|
|
74023
74080
|
function createDoorEventHub() {
|
|
@@ -74124,6 +74181,65 @@ function rcFanoutOnDoorHub(fanout, hub) {
|
|
|
74124
74181
|
};
|
|
74125
74182
|
}
|
|
74126
74183
|
|
|
74184
|
+
// src/frontdoor/quotaExpiringEvents.ts
|
|
74185
|
+
var MS_PER_HOUR2 = 36e5;
|
|
74186
|
+
var MS_PER_DAY2 = 864e5;
|
|
74187
|
+
var FIVE_HOUR_WINDOW_HOURS = 5;
|
|
74188
|
+
var SEVEN_DAY_WINDOW_DAYS = 7;
|
|
74189
|
+
var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR2;
|
|
74190
|
+
var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY2;
|
|
74191
|
+
var FINAL_SPAN_DENOMINATOR = 30;
|
|
74192
|
+
var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
|
|
74193
|
+
function createQuotaExpiringPublisher(hub, deps) {
|
|
74194
|
+
const publisher = hub.publisher(QUOTA_EXPIRING_EVENT_SOURCE);
|
|
74195
|
+
const latest = /* @__PURE__ */ new Map();
|
|
74196
|
+
for (const snapshot of deps.seed) {
|
|
74197
|
+
latest.set(snapshot.identity, snapshot);
|
|
74198
|
+
}
|
|
74199
|
+
hub.subscribe([USAGE_EVENT_SOURCE], (event) => {
|
|
74200
|
+
const snapshot = UsageSnapshotSchema.parse(event.payload);
|
|
74201
|
+
latest.set(snapshot.identity, snapshot);
|
|
74202
|
+
});
|
|
74203
|
+
const announced = /* @__PURE__ */ new Set();
|
|
74204
|
+
const windowsOf = (snapshot) => {
|
|
74205
|
+
const views = [];
|
|
74206
|
+
for (const provider of Object.keys(snapshot.providers).sort()) {
|
|
74207
|
+
const unified = snapshot.providers[provider]?.rateLimit?.unified;
|
|
74208
|
+
const fiveHour = unified?.fiveHour;
|
|
74209
|
+
if (fiveHour?.utilization !== void 0 && fiveHour.resetsAt !== void 0) {
|
|
74210
|
+
views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS2, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
|
|
74211
|
+
}
|
|
74212
|
+
const sevenDay = unified?.sevenDay;
|
|
74213
|
+
if (sevenDay?.utilization !== void 0 && sevenDay.resetsAt !== void 0) {
|
|
74214
|
+
views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS2, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
|
|
74215
|
+
}
|
|
74216
|
+
}
|
|
74217
|
+
return views;
|
|
74218
|
+
};
|
|
74219
|
+
return {
|
|
74220
|
+
check: () => {
|
|
74221
|
+
const now = deps.now();
|
|
74222
|
+
for (const identity of [...latest.keys()].sort()) {
|
|
74223
|
+
const snapshot = latest.get(identity);
|
|
74224
|
+
if (snapshot === void 0) {
|
|
74225
|
+
continue;
|
|
74226
|
+
}
|
|
74227
|
+
for (const { provider, view } of windowsOf(snapshot)) {
|
|
74228
|
+
if (view.utilization >= 1 || view.resetsAtMs <= now || view.resetsAtMs - now >= view.spanMs * QUOTA_EXPIRING_WINDOW_FRACTION) {
|
|
74229
|
+
continue;
|
|
74230
|
+
}
|
|
74231
|
+
const key = `${identity}:${provider}:${view.window}:${String(view.resetsAtMs)}`;
|
|
74232
|
+
if (announced.has(key)) {
|
|
74233
|
+
continue;
|
|
74234
|
+
}
|
|
74235
|
+
announced.add(key);
|
|
74236
|
+
publisher.publish({ identity, provider, window: view.window, utilization: view.utilization, resetsAt: new Date(view.resetsAtMs).toISOString(), observedAt: now });
|
|
74237
|
+
}
|
|
74238
|
+
}
|
|
74239
|
+
}
|
|
74240
|
+
};
|
|
74241
|
+
}
|
|
74242
|
+
|
|
74127
74243
|
// src/frontdoor/launchEvents.ts
|
|
74128
74244
|
function createLaunchEventPublisher(hub, now) {
|
|
74129
74245
|
const publisher = hub.publisher(LAUNCH_EVENT_SOURCE);
|
|
@@ -78260,7 +78376,7 @@ var OPENROUTER_HOST = "openrouter.ai";
|
|
|
78260
78376
|
var OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
78261
78377
|
var OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
78262
78378
|
var HTTP_FORBIDDEN = 403;
|
|
78263
|
-
var
|
|
78379
|
+
var MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND10;
|
|
78264
78380
|
var OpenRouterKeySchema = external_exports.object({
|
|
78265
78381
|
data: external_exports.object({
|
|
78266
78382
|
limit: external_exports.number().nonnegative().nullable(),
|
|
@@ -78292,7 +78408,7 @@ async function openRouterGet(url2, schema, apiKey, http8, signal) {
|
|
|
78292
78408
|
return parsed.data;
|
|
78293
78409
|
}
|
|
78294
78410
|
function nextUtcMidnight(nowMs) {
|
|
78295
|
-
return new Date((Math.floor(nowMs /
|
|
78411
|
+
return new Date((Math.floor(nowMs / MS_PER_DAY3) + 1) * MS_PER_DAY3).toISOString();
|
|
78296
78412
|
}
|
|
78297
78413
|
var openRouterQuotaAdapter = {
|
|
78298
78414
|
source: OPENROUTER_SOURCE,
|
|
@@ -78314,7 +78430,7 @@ var openRouterQuotaAdapter = {
|
|
|
78314
78430
|
windows.push({ measures: "account-credits", period: "prepaid", utilization: used / total, limit: total, used, remaining: Math.max(total - used, 0) });
|
|
78315
78431
|
}
|
|
78316
78432
|
if (free !== void 0 && free.limit > 0) {
|
|
78317
|
-
windows.push({ measures: "free-model-requests", periodMs:
|
|
78433
|
+
windows.push({ measures: "free-model-requests", periodMs: MS_PER_DAY3, utilization: free.used / free.limit, resetsAt: nextUtcMidnight(nowMs), limit: free.limit, used: free.used, remaining: Math.max(free.remaining, 0) });
|
|
78318
78434
|
}
|
|
78319
78435
|
return ProviderQuotaSchema.parse({
|
|
78320
78436
|
observedAt: new Date(nowMs).toISOString(),
|
|
@@ -78503,6 +78619,9 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78503
78619
|
const rcCredentialStore = createRcCredentialStore(realFarmFs, paths.frontdoorRcCredentialsDir);
|
|
78504
78620
|
const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS, credentialStore: rcCredentialStore });
|
|
78505
78621
|
const doorEvents = createDoorEventHub();
|
|
78622
|
+
const usagePublisher = doorEvents.publisher(USAGE_EVENT_SOURCE);
|
|
78623
|
+
const quotaExpiring = createQuotaExpiringPublisher(doorEvents, { seed: listUsageSnapshots(realFarmFs, paths.usageSnapshotsDir), now: () => Date.now() });
|
|
78624
|
+
const doorHealth = createDoorHealthPublisher(doorEvents, () => Date.now(), process.pid);
|
|
78506
78625
|
const rcLiveUsage = createRcLiveUsage({ now: () => Date.now(), hub: doorEvents });
|
|
78507
78626
|
const rcFanout = rcFanoutOnDoorHub(createRcEventFanout(), doorEvents);
|
|
78508
78627
|
const rcHub = createRcStreamHub({
|
|
@@ -78548,7 +78667,10 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78548
78667
|
pid: process.pid,
|
|
78549
78668
|
now: () => Date.now(),
|
|
78550
78669
|
readAccount: createAccountReader(realFarmFs, paths.identitiesDir),
|
|
78551
|
-
log
|
|
78670
|
+
log,
|
|
78671
|
+
publish: (snapshot) => {
|
|
78672
|
+
usagePublisher.publish(snapshot);
|
|
78673
|
+
}
|
|
78552
78674
|
});
|
|
78553
78675
|
const quotaRefresher = createRealQuotaRefresher({ paths, store: usageStore, log });
|
|
78554
78676
|
const usageMiddleware = createUsageMiddleware({
|
|
@@ -78614,7 +78736,13 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78614
78736
|
now: () => Date.now(),
|
|
78615
78737
|
frontDoorStatus: () => collectFrontDoorStatus(realFarmFs, realHeadroomSocketTrust, paths, realIsProcessRunning),
|
|
78616
78738
|
checkReport: (target, identity) => collectCheckReport({ paths, cwd: target, ...identity === void 0 ? {} : { identity }, env: process.env }),
|
|
78617
|
-
doctorReport: () => collectDoctorReport({ paths, env: process.env })
|
|
78739
|
+
doctorReport: () => collectDoctorReport({ paths, env: process.env }),
|
|
78740
|
+
// The pool table is read per call, not captured here, so a pool created or removed after the door started is ranked or refused by its live name the same moment the CLI would see it.
|
|
78741
|
+
poolPick: (pool, directory) => {
|
|
78742
|
+
const pools = readPools(paths);
|
|
78743
|
+
return pools[pool] === void 0 ? void 0 : collectPoolPick({ paths, fs: realFsPort, usageFs: realFarmFs, poolName: pool, pools, directory, nowMs: Date.now() });
|
|
78744
|
+
},
|
|
78745
|
+
poolNames: () => Object.keys(readPools(paths)).sort()
|
|
78618
78746
|
};
|
|
78619
78747
|
realFarmFs.mkdirp(paths.frontdoorDir);
|
|
78620
78748
|
realFarmFs.writeFilePrivate(paths.frontdoorControlTokenFile, `${rcControlToken}
|
|
@@ -78741,6 +78869,8 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78741
78869
|
closeRcStreamHub: rcHub.close,
|
|
78742
78870
|
// The launch lifecycle publisher over the same backbone the typed API serves: the tick's registry facts go in here, and the door's own register, prune and end moments come out as source-tagged events.
|
|
78743
78871
|
observeLaunchRegistry: createLaunchEventPublisher(doorEvents, () => Date.now()).observe,
|
|
78872
|
+
doorHealth,
|
|
78873
|
+
checkQuotaExpiry: quotaExpiring.check,
|
|
78744
78874
|
log: (line) => {
|
|
78745
78875
|
appendLog(paths, line);
|
|
78746
78876
|
}
|
|
@@ -80559,13 +80689,13 @@ function formatLimit(limit) {
|
|
|
80559
80689
|
return `last limit: ${limit.kind} (${String(limit.status)}) at ${limit.observedAt}${limit.window === void 0 ? "" : ` on the ${limit.window} window`}${wait.length === 0 ? "" : `, ${wait.join(", ")}`}`;
|
|
80560
80690
|
}
|
|
80561
80691
|
var MONEY_DECIMALS = 2;
|
|
80562
|
-
var
|
|
80692
|
+
var MS_PER_HOUR3 = 36e5;
|
|
80563
80693
|
var HOURS_PER_DAY4 = 24;
|
|
80564
80694
|
function formatPeriod(window) {
|
|
80565
80695
|
if (window.periodMs === void 0) {
|
|
80566
80696
|
return window.period ?? "unknown period";
|
|
80567
80697
|
}
|
|
80568
|
-
const hours = window.periodMs /
|
|
80698
|
+
const hours = window.periodMs / MS_PER_HOUR3;
|
|
80569
80699
|
return hours >= HOURS_PER_DAY4 && Number.isInteger(hours / HOURS_PER_DAY4) ? `${String(hours / HOURS_PER_DAY4)}d` : `${String(hours)}h`;
|
|
80570
80700
|
}
|
|
80571
80701
|
function formatCount(value2) {
|
package/dist/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ __export(index_exports, {
|
|
|
48
48
|
CredentialSourceSchema: () => CredentialSourceSchema,
|
|
49
49
|
DOOR_EVENT_BUFFER_EVENTS: () => DOOR_EVENT_BUFFER_EVENTS,
|
|
50
50
|
DOOR_EVENT_SOURCE_RC: () => DOOR_EVENT_SOURCE_RC,
|
|
51
|
+
DOOR_HEALTH_EVENT_SOURCE: () => DOOR_HEALTH_EVENT_SOURCE,
|
|
51
52
|
DirectoryRuleAlreadyExistsError: () => DirectoryRuleAlreadyExistsError,
|
|
52
53
|
DirectoryRuleMissingTargetError: () => DirectoryRuleMissingTargetError,
|
|
53
54
|
DirectoryRuleNotFoundError: () => DirectoryRuleNotFoundError,
|
|
@@ -57,6 +58,7 @@ __export(index_exports, {
|
|
|
57
58
|
DoctorRunOutputSchema: () => DoctorRunOutputSchema,
|
|
58
59
|
DoorEventSchema: () => DoorEventSchema,
|
|
59
60
|
DoorEventSourceQuerySchema: () => DoorEventSourceQuerySchema,
|
|
61
|
+
DoorHealthEventSchema: () => DoorHealthEventSchema,
|
|
60
62
|
EXIT_FAILURE: () => EXIT_FAILURE,
|
|
61
63
|
EXIT_USAGE: () => EXIT_USAGE,
|
|
62
64
|
EffectiveWindowSchema: () => EffectiveWindowSchema,
|
|
@@ -93,6 +95,8 @@ __export(index_exports, {
|
|
|
93
95
|
ProviderKindMismatchError: () => ProviderKindMismatchError,
|
|
94
96
|
ProviderNotFoundError: () => ProviderNotFoundError,
|
|
95
97
|
ProviderSchema: () => ProviderSchema,
|
|
98
|
+
QUOTA_EXPIRING_EVENT_SOURCE: () => QUOTA_EXPIRING_EVENT_SOURCE,
|
|
99
|
+
QuotaExpiringEventSchema: () => QuotaExpiringEventSchema,
|
|
96
100
|
RC_CONTEXT_USAGE_DETAILS: () => RC_CONTEXT_USAGE_DETAILS,
|
|
97
101
|
RC_IDLE_EXPIRY_MS: () => RC_IDLE_EXPIRY_MS,
|
|
98
102
|
RC_ORPC_PATH_PREFIX: () => RC_ORPC_PATH_PREFIX,
|
|
@@ -120,6 +124,7 @@ __export(index_exports, {
|
|
|
120
124
|
RcRateLimitWindowSchema: () => RcRateLimitWindowSchema,
|
|
121
125
|
RcStreamEnvelopeSchema: () => RcStreamEnvelopeSchema,
|
|
122
126
|
RcStreamEventSchema: () => RcStreamEventSchema,
|
|
127
|
+
USAGE_EVENT_SOURCE: () => USAGE_EVENT_SOURCE,
|
|
123
128
|
UsageError: () => UsageError,
|
|
124
129
|
UsageListOutputSchema: () => UsageListOutputSchema,
|
|
125
130
|
UsageLiveOutputSchema: () => UsageLiveOutputSchema,
|
|
@@ -165,10 +170,12 @@ __export(index_exports, {
|
|
|
165
170
|
createDoorApiNodeHandler: () => createDoorApiNodeHandler,
|
|
166
171
|
createDoorApiRouter: () => createDoorApiRouter,
|
|
167
172
|
createDoorEventHub: () => createDoorEventHub,
|
|
173
|
+
createDoorHealthPublisher: () => createDoorHealthPublisher,
|
|
168
174
|
createEventsApiRouter: () => createEventsApiRouter,
|
|
169
175
|
createLaunchEventPublisher: () => createLaunchEventPublisher,
|
|
170
176
|
createLeafCache: () => createLeafCache,
|
|
171
177
|
createProfile: () => createProfile,
|
|
178
|
+
createQuotaExpiringPublisher: () => createQuotaExpiringPublisher,
|
|
172
179
|
createRcApiNodeHandler: () => createRcApiNodeHandler,
|
|
173
180
|
createRcApiRouter: () => createRcApiRouter,
|
|
174
181
|
createRcControlHandler: () => createRcControlHandler,
|
|
@@ -3034,6 +3041,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3034
3041
|
try {
|
|
3035
3042
|
http3 = await ports.startProviderListener(lastPort);
|
|
3036
3043
|
} catch (error) {
|
|
3044
|
+
ports.doorHealth.listenerFailed("provider", error instanceof Error ? error.message : String(error));
|
|
3037
3045
|
return fail(`could not start the provider listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
3038
3046
|
}
|
|
3039
3047
|
if (previousSticky !== void 0 && http3.port !== previousSticky) {
|
|
@@ -3046,6 +3054,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3046
3054
|
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
3047
3055
|
} catch (error) {
|
|
3048
3056
|
await http3.close();
|
|
3057
|
+
ports.doorHealth.listenerFailed("connect", error instanceof Error ? error.message : String(error));
|
|
3049
3058
|
return fail(`could not start the CONNECT surface: ${error instanceof Error ? error.message : String(error)}`);
|
|
3050
3059
|
}
|
|
3051
3060
|
if (previousStickyConnect !== void 0 && connect3.port !== previousStickyConnect) {
|
|
@@ -3059,6 +3068,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3059
3068
|
} catch (error) {
|
|
3060
3069
|
await connect3.close();
|
|
3061
3070
|
await http3.close();
|
|
3071
|
+
ports.doorHealth.listenerFailed("direct", error instanceof Error ? error.message : String(error));
|
|
3062
3072
|
return fail(`could not start the direct listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
3063
3073
|
}
|
|
3064
3074
|
if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
|
|
@@ -3066,6 +3076,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3066
3076
|
}
|
|
3067
3077
|
lastDirectPort = direct.port;
|
|
3068
3078
|
writeFrontDoorState(fs12, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
3079
|
+
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
3069
3080
|
fs12.removeRecursive(paths.frontdoorLockFile);
|
|
3070
3081
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
3071
3082
|
let idleSince;
|
|
@@ -3078,11 +3089,13 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3078
3089
|
const listed = listFrontDoorSessions(fs12, paths.frontdoorSessionsDir);
|
|
3079
3090
|
const pruned = pruneDeadFrontDoorSessions(fs12, paths.frontdoorSessionsDir, ports.isRunning);
|
|
3080
3091
|
ports.observeLaunchRegistry(listed, pruned);
|
|
3092
|
+
ports.checkQuotaExpiry();
|
|
3081
3093
|
const prunedPids = new Set(pruned);
|
|
3082
3094
|
if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
|
|
3083
3095
|
idleSince ??= ports.now();
|
|
3084
3096
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
3085
3097
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
3098
|
+
ports.doorHealth.idleShutdown();
|
|
3086
3099
|
await direct.close();
|
|
3087
3100
|
await connect3.close();
|
|
3088
3101
|
await http3.close();
|
|
@@ -5342,7 +5355,7 @@ var import_undici = require("undici");
|
|
|
5342
5355
|
// package.json
|
|
5343
5356
|
var package_default = {
|
|
5344
5357
|
name: "agent-shim",
|
|
5345
|
-
version: "8.
|
|
5358
|
+
version: "8.31.0",
|
|
5346
5359
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
5347
5360
|
license: "MIT",
|
|
5348
5361
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -10180,6 +10193,10 @@ var CheckRunInputSchema = import_zod19.z.strictObject({
|
|
|
10180
10193
|
path: import_zod19.z.string().min(1),
|
|
10181
10194
|
identity: import_zod19.z.string().min(1).optional()
|
|
10182
10195
|
}).refine((input) => import_node_path27.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
10196
|
+
var PoolPickInputSchema = import_zod19.z.strictObject({
|
|
10197
|
+
pool: import_zod19.z.string().min(1),
|
|
10198
|
+
path: import_zod19.z.string().min(1)
|
|
10199
|
+
}).refine((input) => import_node_path27.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
10183
10200
|
var DoctorFindingSchema = import_zod19.z.strictObject({
|
|
10184
10201
|
section: import_zod19.z.enum(DOCTOR_SECTIONS),
|
|
10185
10202
|
subject: import_zod19.z.string().optional(),
|
|
@@ -10200,6 +10217,9 @@ var import_server3 = require("@orpc/server");
|
|
|
10200
10217
|
var import_zod20 = require("zod");
|
|
10201
10218
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
10202
10219
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
10220
|
+
var USAGE_EVENT_SOURCE = "usage";
|
|
10221
|
+
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
10222
|
+
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
10203
10223
|
var DoorEventSchema = import_zod20.z.strictObject({
|
|
10204
10224
|
source: import_zod20.z.string().min(1),
|
|
10205
10225
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
@@ -10215,6 +10235,20 @@ var LaunchLifecycleEventSchema = import_zod20.z.strictObject({
|
|
|
10215
10235
|
startedAt: import_zod20.z.number(),
|
|
10216
10236
|
observedAt: import_zod20.z.number()
|
|
10217
10237
|
});
|
|
10238
|
+
var DoorHealthEventSchema = import_zod20.z.discriminatedUnion("kind", [
|
|
10239
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("generation"), pid: import_zod20.z.number().int().positive(), providerPort: import_zod20.z.number().int().positive(), connectPort: import_zod20.z.number().int().positive(), directPort: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
|
|
10240
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("listenerFailed"), pid: import_zod20.z.number().int().positive(), listener: import_zod20.z.enum(["provider", "connect", "direct"]), message: import_zod20.z.string(), observedAt: import_zod20.z.number() }),
|
|
10241
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("idleShutdown"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() })
|
|
10242
|
+
]);
|
|
10243
|
+
var QuotaExpiringEventSchema = import_zod20.z.strictObject({
|
|
10244
|
+
identity: import_zod20.z.string().min(1),
|
|
10245
|
+
provider: import_zod20.z.string().min(1),
|
|
10246
|
+
window: import_zod20.z.enum(["fiveHour", "sevenDay"]),
|
|
10247
|
+
/** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
|
|
10248
|
+
utilization: import_zod20.z.number().min(0).max(1),
|
|
10249
|
+
resetsAt: import_zod20.z.iso.datetime(),
|
|
10250
|
+
observedAt: import_zod20.z.number()
|
|
10251
|
+
});
|
|
10218
10252
|
|
|
10219
10253
|
// src/frontdoor/eventsApi.ts
|
|
10220
10254
|
var EVENTS_API_TAG = "events";
|
|
@@ -10259,6 +10293,7 @@ var USAGE_API_TAG = "usage";
|
|
|
10259
10293
|
var FRONTDOOR_API_TAG = "frontdoor";
|
|
10260
10294
|
var CHECK_API_TAG = "check";
|
|
10261
10295
|
var DOCTOR_API_TAG = "doctor";
|
|
10296
|
+
var POOL_API_TAG = "pool";
|
|
10262
10297
|
function createControlApiRouter(deps) {
|
|
10263
10298
|
const authed = doorApiAuth(deps.expectedToken);
|
|
10264
10299
|
return {
|
|
@@ -10302,6 +10337,18 @@ function createControlApiRouter(deps) {
|
|
|
10302
10337
|
},
|
|
10303
10338
|
doctor: {
|
|
10304
10339
|
run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
10340
|
+
},
|
|
10341
|
+
pool: {
|
|
10342
|
+
pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
|
|
10343
|
+
const report = deps.poolPick(input.pool, input.path);
|
|
10344
|
+
if (report === void 0) {
|
|
10345
|
+
const live = deps.poolNames();
|
|
10346
|
+
throw new import_client3.ORPCError("NOT_FOUND", {
|
|
10347
|
+
message: live.length === 0 ? `no pools are configured, so none is named ${input.pool}` : `no pool is named ${input.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
|
|
10348
|
+
});
|
|
10349
|
+
}
|
|
10350
|
+
return report;
|
|
10351
|
+
})
|
|
10305
10352
|
}
|
|
10306
10353
|
};
|
|
10307
10354
|
}
|
|
@@ -10510,6 +10557,81 @@ function createLaunchEventPublisher(hub, now) {
|
|
|
10510
10557
|
};
|
|
10511
10558
|
}
|
|
10512
10559
|
|
|
10560
|
+
// src/frontdoor/doorHealthEvents.ts
|
|
10561
|
+
function createDoorHealthPublisher(hub, now, pid) {
|
|
10562
|
+
const publisher = hub.publisher(DOOR_HEALTH_EVENT_SOURCE);
|
|
10563
|
+
return {
|
|
10564
|
+
generation: (ports) => {
|
|
10565
|
+
publisher.publish({ kind: "generation", pid, providerPort: ports.providerPort, connectPort: ports.connectPort, directPort: ports.directPort, observedAt: now() });
|
|
10566
|
+
},
|
|
10567
|
+
listenerFailed: (listener, message) => {
|
|
10568
|
+
publisher.publish({ kind: "listenerFailed", pid, listener, message, observedAt: now() });
|
|
10569
|
+
},
|
|
10570
|
+
idleShutdown: () => {
|
|
10571
|
+
publisher.publish({ kind: "idleShutdown", pid, observedAt: now() });
|
|
10572
|
+
}
|
|
10573
|
+
};
|
|
10574
|
+
}
|
|
10575
|
+
|
|
10576
|
+
// src/frontdoor/quotaExpiringEvents.ts
|
|
10577
|
+
var MS_PER_HOUR2 = 36e5;
|
|
10578
|
+
var MS_PER_DAY2 = 864e5;
|
|
10579
|
+
var FIVE_HOUR_WINDOW_HOURS = 5;
|
|
10580
|
+
var SEVEN_DAY_WINDOW_DAYS = 7;
|
|
10581
|
+
var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR2;
|
|
10582
|
+
var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY2;
|
|
10583
|
+
var FINAL_SPAN_DENOMINATOR = 30;
|
|
10584
|
+
var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
|
|
10585
|
+
function createQuotaExpiringPublisher(hub, deps) {
|
|
10586
|
+
const publisher = hub.publisher(QUOTA_EXPIRING_EVENT_SOURCE);
|
|
10587
|
+
const latest = /* @__PURE__ */ new Map();
|
|
10588
|
+
for (const snapshot of deps.seed) {
|
|
10589
|
+
latest.set(snapshot.identity, snapshot);
|
|
10590
|
+
}
|
|
10591
|
+
hub.subscribe([USAGE_EVENT_SOURCE], (event) => {
|
|
10592
|
+
const snapshot = UsageSnapshotSchema.parse(event.payload);
|
|
10593
|
+
latest.set(snapshot.identity, snapshot);
|
|
10594
|
+
});
|
|
10595
|
+
const announced = /* @__PURE__ */ new Set();
|
|
10596
|
+
const windowsOf = (snapshot) => {
|
|
10597
|
+
const views = [];
|
|
10598
|
+
for (const provider of Object.keys(snapshot.providers).sort()) {
|
|
10599
|
+
const unified = snapshot.providers[provider]?.rateLimit?.unified;
|
|
10600
|
+
const fiveHour = unified?.fiveHour;
|
|
10601
|
+
if (fiveHour?.utilization !== void 0 && fiveHour.resetsAt !== void 0) {
|
|
10602
|
+
views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS2, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
|
|
10603
|
+
}
|
|
10604
|
+
const sevenDay = unified?.sevenDay;
|
|
10605
|
+
if (sevenDay?.utilization !== void 0 && sevenDay.resetsAt !== void 0) {
|
|
10606
|
+
views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS2, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
|
|
10607
|
+
}
|
|
10608
|
+
}
|
|
10609
|
+
return views;
|
|
10610
|
+
};
|
|
10611
|
+
return {
|
|
10612
|
+
check: () => {
|
|
10613
|
+
const now = deps.now();
|
|
10614
|
+
for (const identity of [...latest.keys()].sort()) {
|
|
10615
|
+
const snapshot = latest.get(identity);
|
|
10616
|
+
if (snapshot === void 0) {
|
|
10617
|
+
continue;
|
|
10618
|
+
}
|
|
10619
|
+
for (const { provider, view } of windowsOf(snapshot)) {
|
|
10620
|
+
if (view.utilization >= 1 || view.resetsAtMs <= now || view.resetsAtMs - now >= view.spanMs * QUOTA_EXPIRING_WINDOW_FRACTION) {
|
|
10621
|
+
continue;
|
|
10622
|
+
}
|
|
10623
|
+
const key = `${identity}:${provider}:${view.window}:${String(view.resetsAtMs)}`;
|
|
10624
|
+
if (announced.has(key)) {
|
|
10625
|
+
continue;
|
|
10626
|
+
}
|
|
10627
|
+
announced.add(key);
|
|
10628
|
+
publisher.publish({ identity, provider, window: view.window, utilization: view.utilization, resetsAt: new Date(view.resetsAtMs).toISOString(), observedAt: now });
|
|
10629
|
+
}
|
|
10630
|
+
}
|
|
10631
|
+
}
|
|
10632
|
+
};
|
|
10633
|
+
}
|
|
10634
|
+
|
|
10513
10635
|
// src/frontdoor/rcLiveUsage.ts
|
|
10514
10636
|
var RC_RATE_LIMIT_EVENT_TYPE = "rate_limit_event";
|
|
10515
10637
|
function isRecord5(value) {
|
|
@@ -13503,6 +13625,7 @@ function prepareClaudeLaunch(options) {
|
|
|
13503
13625
|
CredentialSourceSchema,
|
|
13504
13626
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
13505
13627
|
DOOR_EVENT_SOURCE_RC,
|
|
13628
|
+
DOOR_HEALTH_EVENT_SOURCE,
|
|
13506
13629
|
DirectoryRuleAlreadyExistsError,
|
|
13507
13630
|
DirectoryRuleMissingTargetError,
|
|
13508
13631
|
DirectoryRuleNotFoundError,
|
|
@@ -13512,6 +13635,7 @@ function prepareClaudeLaunch(options) {
|
|
|
13512
13635
|
DoctorRunOutputSchema,
|
|
13513
13636
|
DoorEventSchema,
|
|
13514
13637
|
DoorEventSourceQuerySchema,
|
|
13638
|
+
DoorHealthEventSchema,
|
|
13515
13639
|
EXIT_FAILURE,
|
|
13516
13640
|
EXIT_USAGE,
|
|
13517
13641
|
EffectiveWindowSchema,
|
|
@@ -13548,6 +13672,8 @@ function prepareClaudeLaunch(options) {
|
|
|
13548
13672
|
ProviderKindMismatchError,
|
|
13549
13673
|
ProviderNotFoundError,
|
|
13550
13674
|
ProviderSchema,
|
|
13675
|
+
QUOTA_EXPIRING_EVENT_SOURCE,
|
|
13676
|
+
QuotaExpiringEventSchema,
|
|
13551
13677
|
RC_CONTEXT_USAGE_DETAILS,
|
|
13552
13678
|
RC_IDLE_EXPIRY_MS,
|
|
13553
13679
|
RC_ORPC_PATH_PREFIX,
|
|
@@ -13575,6 +13701,7 @@ function prepareClaudeLaunch(options) {
|
|
|
13575
13701
|
RcRateLimitWindowSchema,
|
|
13576
13702
|
RcStreamEnvelopeSchema,
|
|
13577
13703
|
RcStreamEventSchema,
|
|
13704
|
+
USAGE_EVENT_SOURCE,
|
|
13578
13705
|
UsageError,
|
|
13579
13706
|
UsageListOutputSchema,
|
|
13580
13707
|
UsageLiveOutputSchema,
|
|
@@ -13620,10 +13747,12 @@ function prepareClaudeLaunch(options) {
|
|
|
13620
13747
|
createDoorApiNodeHandler,
|
|
13621
13748
|
createDoorApiRouter,
|
|
13622
13749
|
createDoorEventHub,
|
|
13750
|
+
createDoorHealthPublisher,
|
|
13623
13751
|
createEventsApiRouter,
|
|
13624
13752
|
createLaunchEventPublisher,
|
|
13625
13753
|
createLeafCache,
|
|
13626
13754
|
createProfile,
|
|
13755
|
+
createQuotaExpiringPublisher,
|
|
13627
13756
|
createRcApiNodeHandler,
|
|
13628
13757
|
createRcApiRouter,
|
|
13629
13758
|
createRcControlHandler,
|
package/dist/index.mjs
CHANGED
|
@@ -2729,6 +2729,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2729
2729
|
try {
|
|
2730
2730
|
http3 = await ports.startProviderListener(lastPort);
|
|
2731
2731
|
} catch (error) {
|
|
2732
|
+
ports.doorHealth.listenerFailed("provider", error instanceof Error ? error.message : String(error));
|
|
2732
2733
|
return fail(`could not start the provider listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
2733
2734
|
}
|
|
2734
2735
|
if (previousSticky !== void 0 && http3.port !== previousSticky) {
|
|
@@ -2741,6 +2742,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2741
2742
|
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
2742
2743
|
} catch (error) {
|
|
2743
2744
|
await http3.close();
|
|
2745
|
+
ports.doorHealth.listenerFailed("connect", error instanceof Error ? error.message : String(error));
|
|
2744
2746
|
return fail(`could not start the CONNECT surface: ${error instanceof Error ? error.message : String(error)}`);
|
|
2745
2747
|
}
|
|
2746
2748
|
if (previousStickyConnect !== void 0 && connect3.port !== previousStickyConnect) {
|
|
@@ -2754,6 +2756,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2754
2756
|
} catch (error) {
|
|
2755
2757
|
await connect3.close();
|
|
2756
2758
|
await http3.close();
|
|
2759
|
+
ports.doorHealth.listenerFailed("direct", error instanceof Error ? error.message : String(error));
|
|
2757
2760
|
return fail(`could not start the direct listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
2758
2761
|
}
|
|
2759
2762
|
if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
|
|
@@ -2761,6 +2764,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2761
2764
|
}
|
|
2762
2765
|
lastDirectPort = direct.port;
|
|
2763
2766
|
writeFrontDoorState(fs12, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
2767
|
+
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
2764
2768
|
fs12.removeRecursive(paths.frontdoorLockFile);
|
|
2765
2769
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
2766
2770
|
let idleSince;
|
|
@@ -2773,11 +2777,13 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2773
2777
|
const listed = listFrontDoorSessions(fs12, paths.frontdoorSessionsDir);
|
|
2774
2778
|
const pruned = pruneDeadFrontDoorSessions(fs12, paths.frontdoorSessionsDir, ports.isRunning);
|
|
2775
2779
|
ports.observeLaunchRegistry(listed, pruned);
|
|
2780
|
+
ports.checkQuotaExpiry();
|
|
2776
2781
|
const prunedPids = new Set(pruned);
|
|
2777
2782
|
if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
|
|
2778
2783
|
idleSince ??= ports.now();
|
|
2779
2784
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
2780
2785
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
2786
|
+
ports.doorHealth.idleShutdown();
|
|
2781
2787
|
await direct.close();
|
|
2782
2788
|
await connect3.close();
|
|
2783
2789
|
await http3.close();
|
|
@@ -5037,7 +5043,7 @@ import { Agent as Agent3, fetch as undiciFetch } from "undici";
|
|
|
5037
5043
|
// package.json
|
|
5038
5044
|
var package_default = {
|
|
5039
5045
|
name: "agent-shim",
|
|
5040
|
-
version: "8.
|
|
5046
|
+
version: "8.31.0",
|
|
5041
5047
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
5042
5048
|
license: "MIT",
|
|
5043
5049
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -9875,6 +9881,10 @@ var CheckRunInputSchema = z19.strictObject({
|
|
|
9875
9881
|
path: z19.string().min(1),
|
|
9876
9882
|
identity: z19.string().min(1).optional()
|
|
9877
9883
|
}).refine((input) => path27.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
9884
|
+
var PoolPickInputSchema = z19.strictObject({
|
|
9885
|
+
pool: z19.string().min(1),
|
|
9886
|
+
path: z19.string().min(1)
|
|
9887
|
+
}).refine((input) => path27.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
9878
9888
|
var DoctorFindingSchema = z19.strictObject({
|
|
9879
9889
|
section: z19.enum(DOCTOR_SECTIONS),
|
|
9880
9890
|
subject: z19.string().optional(),
|
|
@@ -9895,6 +9905,9 @@ import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from
|
|
|
9895
9905
|
import { z as z20 } from "zod";
|
|
9896
9906
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
9897
9907
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
9908
|
+
var USAGE_EVENT_SOURCE = "usage";
|
|
9909
|
+
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
9910
|
+
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
9898
9911
|
var DoorEventSchema = z20.strictObject({
|
|
9899
9912
|
source: z20.string().min(1),
|
|
9900
9913
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
@@ -9910,6 +9923,20 @@ var LaunchLifecycleEventSchema = z20.strictObject({
|
|
|
9910
9923
|
startedAt: z20.number(),
|
|
9911
9924
|
observedAt: z20.number()
|
|
9912
9925
|
});
|
|
9926
|
+
var DoorHealthEventSchema = z20.discriminatedUnion("kind", [
|
|
9927
|
+
z20.strictObject({ kind: z20.literal("generation"), pid: z20.number().int().positive(), providerPort: z20.number().int().positive(), connectPort: z20.number().int().positive(), directPort: z20.number().int().positive(), observedAt: z20.number() }),
|
|
9928
|
+
z20.strictObject({ kind: z20.literal("listenerFailed"), pid: z20.number().int().positive(), listener: z20.enum(["provider", "connect", "direct"]), message: z20.string(), observedAt: z20.number() }),
|
|
9929
|
+
z20.strictObject({ kind: z20.literal("idleShutdown"), pid: z20.number().int().positive(), observedAt: z20.number() })
|
|
9930
|
+
]);
|
|
9931
|
+
var QuotaExpiringEventSchema = z20.strictObject({
|
|
9932
|
+
identity: z20.string().min(1),
|
|
9933
|
+
provider: z20.string().min(1),
|
|
9934
|
+
window: z20.enum(["fiveHour", "sevenDay"]),
|
|
9935
|
+
/** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
|
|
9936
|
+
utilization: z20.number().min(0).max(1),
|
|
9937
|
+
resetsAt: z20.iso.datetime(),
|
|
9938
|
+
observedAt: z20.number()
|
|
9939
|
+
});
|
|
9913
9940
|
|
|
9914
9941
|
// src/frontdoor/eventsApi.ts
|
|
9915
9942
|
var EVENTS_API_TAG = "events";
|
|
@@ -9954,6 +9981,7 @@ var USAGE_API_TAG = "usage";
|
|
|
9954
9981
|
var FRONTDOOR_API_TAG = "frontdoor";
|
|
9955
9982
|
var CHECK_API_TAG = "check";
|
|
9956
9983
|
var DOCTOR_API_TAG = "doctor";
|
|
9984
|
+
var POOL_API_TAG = "pool";
|
|
9957
9985
|
function createControlApiRouter(deps) {
|
|
9958
9986
|
const authed = doorApiAuth(deps.expectedToken);
|
|
9959
9987
|
return {
|
|
@@ -9997,6 +10025,18 @@ function createControlApiRouter(deps) {
|
|
|
9997
10025
|
},
|
|
9998
10026
|
doctor: {
|
|
9999
10027
|
run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
10028
|
+
},
|
|
10029
|
+
pool: {
|
|
10030
|
+
pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
|
|
10031
|
+
const report = deps.poolPick(input.pool, input.path);
|
|
10032
|
+
if (report === void 0) {
|
|
10033
|
+
const live = deps.poolNames();
|
|
10034
|
+
throw new ORPCError3("NOT_FOUND", {
|
|
10035
|
+
message: live.length === 0 ? `no pools are configured, so none is named ${input.pool}` : `no pool is named ${input.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
|
|
10036
|
+
});
|
|
10037
|
+
}
|
|
10038
|
+
return report;
|
|
10039
|
+
})
|
|
10000
10040
|
}
|
|
10001
10041
|
};
|
|
10002
10042
|
}
|
|
@@ -10205,6 +10245,81 @@ function createLaunchEventPublisher(hub, now) {
|
|
|
10205
10245
|
};
|
|
10206
10246
|
}
|
|
10207
10247
|
|
|
10248
|
+
// src/frontdoor/doorHealthEvents.ts
|
|
10249
|
+
function createDoorHealthPublisher(hub, now, pid) {
|
|
10250
|
+
const publisher = hub.publisher(DOOR_HEALTH_EVENT_SOURCE);
|
|
10251
|
+
return {
|
|
10252
|
+
generation: (ports) => {
|
|
10253
|
+
publisher.publish({ kind: "generation", pid, providerPort: ports.providerPort, connectPort: ports.connectPort, directPort: ports.directPort, observedAt: now() });
|
|
10254
|
+
},
|
|
10255
|
+
listenerFailed: (listener, message) => {
|
|
10256
|
+
publisher.publish({ kind: "listenerFailed", pid, listener, message, observedAt: now() });
|
|
10257
|
+
},
|
|
10258
|
+
idleShutdown: () => {
|
|
10259
|
+
publisher.publish({ kind: "idleShutdown", pid, observedAt: now() });
|
|
10260
|
+
}
|
|
10261
|
+
};
|
|
10262
|
+
}
|
|
10263
|
+
|
|
10264
|
+
// src/frontdoor/quotaExpiringEvents.ts
|
|
10265
|
+
var MS_PER_HOUR2 = 36e5;
|
|
10266
|
+
var MS_PER_DAY2 = 864e5;
|
|
10267
|
+
var FIVE_HOUR_WINDOW_HOURS = 5;
|
|
10268
|
+
var SEVEN_DAY_WINDOW_DAYS = 7;
|
|
10269
|
+
var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR2;
|
|
10270
|
+
var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY2;
|
|
10271
|
+
var FINAL_SPAN_DENOMINATOR = 30;
|
|
10272
|
+
var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
|
|
10273
|
+
function createQuotaExpiringPublisher(hub, deps) {
|
|
10274
|
+
const publisher = hub.publisher(QUOTA_EXPIRING_EVENT_SOURCE);
|
|
10275
|
+
const latest = /* @__PURE__ */ new Map();
|
|
10276
|
+
for (const snapshot of deps.seed) {
|
|
10277
|
+
latest.set(snapshot.identity, snapshot);
|
|
10278
|
+
}
|
|
10279
|
+
hub.subscribe([USAGE_EVENT_SOURCE], (event) => {
|
|
10280
|
+
const snapshot = UsageSnapshotSchema.parse(event.payload);
|
|
10281
|
+
latest.set(snapshot.identity, snapshot);
|
|
10282
|
+
});
|
|
10283
|
+
const announced = /* @__PURE__ */ new Set();
|
|
10284
|
+
const windowsOf = (snapshot) => {
|
|
10285
|
+
const views = [];
|
|
10286
|
+
for (const provider of Object.keys(snapshot.providers).sort()) {
|
|
10287
|
+
const unified = snapshot.providers[provider]?.rateLimit?.unified;
|
|
10288
|
+
const fiveHour = unified?.fiveHour;
|
|
10289
|
+
if (fiveHour?.utilization !== void 0 && fiveHour.resetsAt !== void 0) {
|
|
10290
|
+
views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS2, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
|
|
10291
|
+
}
|
|
10292
|
+
const sevenDay = unified?.sevenDay;
|
|
10293
|
+
if (sevenDay?.utilization !== void 0 && sevenDay.resetsAt !== void 0) {
|
|
10294
|
+
views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS2, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
|
|
10295
|
+
}
|
|
10296
|
+
}
|
|
10297
|
+
return views;
|
|
10298
|
+
};
|
|
10299
|
+
return {
|
|
10300
|
+
check: () => {
|
|
10301
|
+
const now = deps.now();
|
|
10302
|
+
for (const identity of [...latest.keys()].sort()) {
|
|
10303
|
+
const snapshot = latest.get(identity);
|
|
10304
|
+
if (snapshot === void 0) {
|
|
10305
|
+
continue;
|
|
10306
|
+
}
|
|
10307
|
+
for (const { provider, view } of windowsOf(snapshot)) {
|
|
10308
|
+
if (view.utilization >= 1 || view.resetsAtMs <= now || view.resetsAtMs - now >= view.spanMs * QUOTA_EXPIRING_WINDOW_FRACTION) {
|
|
10309
|
+
continue;
|
|
10310
|
+
}
|
|
10311
|
+
const key = `${identity}:${provider}:${view.window}:${String(view.resetsAtMs)}`;
|
|
10312
|
+
if (announced.has(key)) {
|
|
10313
|
+
continue;
|
|
10314
|
+
}
|
|
10315
|
+
announced.add(key);
|
|
10316
|
+
publisher.publish({ identity, provider, window: view.window, utilization: view.utilization, resetsAt: new Date(view.resetsAtMs).toISOString(), observedAt: now });
|
|
10317
|
+
}
|
|
10318
|
+
}
|
|
10319
|
+
}
|
|
10320
|
+
};
|
|
10321
|
+
}
|
|
10322
|
+
|
|
10208
10323
|
// src/frontdoor/rcLiveUsage.ts
|
|
10209
10324
|
var RC_RATE_LIMIT_EVENT_TYPE = "rate_limit_event";
|
|
10210
10325
|
function isRecord5(value) {
|
|
@@ -13197,6 +13312,7 @@ export {
|
|
|
13197
13312
|
CredentialSourceSchema,
|
|
13198
13313
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
13199
13314
|
DOOR_EVENT_SOURCE_RC,
|
|
13315
|
+
DOOR_HEALTH_EVENT_SOURCE,
|
|
13200
13316
|
DirectoryRuleAlreadyExistsError,
|
|
13201
13317
|
DirectoryRuleMissingTargetError,
|
|
13202
13318
|
DirectoryRuleNotFoundError,
|
|
@@ -13206,6 +13322,7 @@ export {
|
|
|
13206
13322
|
DoctorRunOutputSchema,
|
|
13207
13323
|
DoorEventSchema,
|
|
13208
13324
|
DoorEventSourceQuerySchema,
|
|
13325
|
+
DoorHealthEventSchema,
|
|
13209
13326
|
EXIT_FAILURE,
|
|
13210
13327
|
EXIT_USAGE,
|
|
13211
13328
|
EffectiveWindowSchema,
|
|
@@ -13242,6 +13359,8 @@ export {
|
|
|
13242
13359
|
ProviderKindMismatchError,
|
|
13243
13360
|
ProviderNotFoundError,
|
|
13244
13361
|
ProviderSchema,
|
|
13362
|
+
QUOTA_EXPIRING_EVENT_SOURCE,
|
|
13363
|
+
QuotaExpiringEventSchema,
|
|
13245
13364
|
RC_CONTEXT_USAGE_DETAILS,
|
|
13246
13365
|
RC_IDLE_EXPIRY_MS,
|
|
13247
13366
|
RC_ORPC_PATH_PREFIX,
|
|
@@ -13269,6 +13388,7 @@ export {
|
|
|
13269
13388
|
RcRateLimitWindowSchema,
|
|
13270
13389
|
RcStreamEnvelopeSchema,
|
|
13271
13390
|
RcStreamEventSchema,
|
|
13391
|
+
USAGE_EVENT_SOURCE,
|
|
13272
13392
|
UsageError,
|
|
13273
13393
|
UsageListOutputSchema,
|
|
13274
13394
|
UsageLiveOutputSchema,
|
|
@@ -13314,10 +13434,12 @@ export {
|
|
|
13314
13434
|
createDoorApiNodeHandler,
|
|
13315
13435
|
createDoorApiRouter,
|
|
13316
13436
|
createDoorEventHub,
|
|
13437
|
+
createDoorHealthPublisher,
|
|
13317
13438
|
createEventsApiRouter,
|
|
13318
13439
|
createLaunchEventPublisher,
|
|
13319
13440
|
createLeafCache,
|
|
13320
13441
|
createProfile,
|
|
13442
|
+
createQuotaExpiringPublisher,
|
|
13321
13443
|
createRcApiNodeHandler,
|
|
13322
13444
|
createRcApiRouter,
|
|
13323
13445
|
createRcControlHandler,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3760,6 +3760,12 @@ type UsageSnapshot = z.infer<typeof UsageSnapshotSchema>;
|
|
|
3760
3760
|
declare const DOOR_EVENT_SOURCE_RC = "rc";
|
|
3761
3761
|
/** The source tag every launch lifecycle event carries: the registry's own register, prune and end moments, the first publisher the door itself owns. */
|
|
3762
3762
|
declare const LAUNCH_EVENT_SOURCE = "launch";
|
|
3763
|
+
/** The source tag every usage change event carries: one event per usage snapshot the door writes, the durable fact a quota consumer diffs or reads windows from. */
|
|
3764
|
+
declare const USAGE_EVENT_SOURCE = "usage";
|
|
3765
|
+
/** The source tag every door health event carries: the supervisor's own state transitions, the moments a consumer of the door needs to know the door itself changed. */
|
|
3766
|
+
declare const DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
3767
|
+
/** The source tag every expiring-quota event carries: an identity whose unused window allowance is about to reset, computed from the same snapshots the usage source keeps fresh. */
|
|
3768
|
+
declare const QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
3763
3769
|
/** One event on the door's backbone, exactly as the subscription yields it: the source that published it, the sequence the backbone assigned that source, and the publisher's own payload carried verbatim for the consumer to narrow. */
|
|
3764
3770
|
declare const DoorEventSchema: z.ZodObject<{
|
|
3765
3771
|
source: z.ZodString;
|
|
@@ -3789,6 +3795,54 @@ declare const LaunchLifecycleEventSchema: z.ZodObject<{
|
|
|
3789
3795
|
}, z.core.$strict>;
|
|
3790
3796
|
/** One launch lifecycle event, as the TypeScript the publisher emits and its consumers handle. */
|
|
3791
3797
|
type LaunchLifecycleEvent = z.output<typeof LaunchLifecycleEventSchema>;
|
|
3798
|
+
/**
|
|
3799
|
+
* One door health event: the supervisor's own state transitions, observed at the moment they happened in this process. `generation` is the door fully serving (every listener bound and the state file naming it); `listenerFailed` is a start failure that ends the generation, naming which listener and why; `idleShutdown` is the door closing itself with an empty session registry.
|
|
3800
|
+
*/
|
|
3801
|
+
declare const DoorHealthEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3802
|
+
kind: z.ZodLiteral<"generation">;
|
|
3803
|
+
pid: z.ZodNumber;
|
|
3804
|
+
providerPort: z.ZodNumber;
|
|
3805
|
+
connectPort: z.ZodNumber;
|
|
3806
|
+
directPort: z.ZodNumber;
|
|
3807
|
+
observedAt: z.ZodNumber;
|
|
3808
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
3809
|
+
kind: z.ZodLiteral<"listenerFailed">;
|
|
3810
|
+
pid: z.ZodNumber;
|
|
3811
|
+
listener: z.ZodEnum<{
|
|
3812
|
+
provider: "provider";
|
|
3813
|
+
connect: "connect";
|
|
3814
|
+
direct: "direct";
|
|
3815
|
+
}>;
|
|
3816
|
+
message: z.ZodString;
|
|
3817
|
+
observedAt: z.ZodNumber;
|
|
3818
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
3819
|
+
kind: z.ZodLiteral<"idleShutdown">;
|
|
3820
|
+
pid: z.ZodNumber;
|
|
3821
|
+
observedAt: z.ZodNumber;
|
|
3822
|
+
}, z.core.$strict>], "kind">;
|
|
3823
|
+
/** One door health event, as the TypeScript the publisher emits and its consumers handle. */
|
|
3824
|
+
type DoorHealthEvent = z.output<typeof DoorHealthEventSchema>;
|
|
3825
|
+
/**
|
|
3826
|
+
* One expiring-quota event: an identity's window with allowance still unspent that is about to reset, published once when the window enters its final span (so a scheduler can spend what would otherwise be lost, the moment spending it is still possible). `resetsAt` is the window's own reset instant; `observedAt` is when the door's tick saw it cross.
|
|
3827
|
+
*/
|
|
3828
|
+
declare const QuotaExpiringEventSchema: z.ZodObject<{
|
|
3829
|
+
identity: z.ZodString;
|
|
3830
|
+
provider: z.ZodString;
|
|
3831
|
+
window: z.ZodEnum<{
|
|
3832
|
+
fiveHour: "fiveHour";
|
|
3833
|
+
sevenDay: "sevenDay";
|
|
3834
|
+
}>;
|
|
3835
|
+
utilization: z.ZodNumber;
|
|
3836
|
+
resetsAt: z.ZodISODateTime;
|
|
3837
|
+
observedAt: z.ZodNumber;
|
|
3838
|
+
}, z.core.$strict>;
|
|
3839
|
+
/** One expiring-quota event, as the TypeScript the publisher emits and its consumers handle. */
|
|
3840
|
+
type QuotaExpiringEvent = z.output<typeof QuotaExpiringEventSchema>;
|
|
3841
|
+
/**
|
|
3842
|
+
* The usage source's payload: the snapshot the door just wrote, verbatim, so a consumer sees the quota change or reset in the payload itself rather than the door guessing which of the two a write was. The snapshot schema is the payload schema (identity, observed instant, every provider's state with its windows), the one definition `usage --json` readers already share.
|
|
3843
|
+
*/
|
|
3844
|
+
/** One usage change event, as the TypeScript the publisher emits and its consumers handle: the written snapshot itself, so the snapshot's own schema (`UsageSnapshotSchema`) is this payload's schema rather than a renamed copy. */
|
|
3845
|
+
type UsageChangeEvent = UsageSnapshot;
|
|
3792
3846
|
|
|
3793
3847
|
/**
|
|
3794
3848
|
* The door's event backbone: the publisher/subscriber machinery the Remote Control client stream's fan-out first proved, generalised so any door-wide source can publish and any consumer can subscribe once instead of each source growing its own channel. A publisher registers under a source tag and publishes payloads; the backbone stamps each event with its source's own monotonic sequence and delivers to every matching subscriber synchronously, in publication order. A source that carries its own ordering on the wire (the Remote Control envelope's per-session `sequence_num`, the number its resume rule resumes after) keeps it inside the payload, verbatim: the backbone's sequence is deliberately not any protocol's number.
|
|
@@ -3915,6 +3969,7 @@ declare function formatFrontDoorStatus(status: FrontDoorStatus, caCertPath: stri
|
|
|
3915
3969
|
* - `usage.*` reads the per-identity usage snapshots the door's own middleware writes, reads a provider's quota windows the way every in-process consumer does (`effectiveWindow`: a window past its reset is empty and carries no status), and reads the live rate-limit observations the event backbone files off the Remote Control client stream (`live`: per-session latest state, exactly as fresh as the last turn a session completed, never a timer's derivation of it).
|
|
3916
3970
|
* - `frontdoor.*` returns what `agent-shim frontdoor status` returns: the supervisor state, its liveness, the session registry's launches and the headroom hop.
|
|
3917
3971
|
* - `check.run` and `doctor.run` return the reports `agent-shim check` and `agent-shim doctor` print, as data, `check.run` parameterised by an absolute directory path.
|
|
3972
|
+
* - `pool.pick` returns what `agent-shim pool pick` prints, the ranked pick for one pool exactly as a launch from the named absolute directory would make it right now, so a programmatic consumer can ask which identity to use without reading the door host's files.
|
|
3918
3973
|
*
|
|
3919
3974
|
* Read-only by design: identity, configuration-profile, provider, pool and directory-rule management stay CLI-side, and adding writes over this mount is a decision of its own rather than a gap here. `createDoorApiNodeHandler` mounts these routers and the door-wide `events.subscribe` router beside the Remote Control router on the one prefix the provider listener already serves, so a consumer dials one address with one token for the whole door.
|
|
3920
3975
|
*/
|
|
@@ -3940,6 +3995,10 @@ interface ControlApiDeps {
|
|
|
3940
3995
|
readonly checkReport: (path: string, identity?: string) => CheckReport;
|
|
3941
3996
|
/** The doctor report, as `collectDoctorReport` collects it. */
|
|
3942
3997
|
readonly doctorReport: () => DoctorReport;
|
|
3998
|
+
/** The ranked pick for one pool as a launch from one absolute directory would make it right now, exactly `pool pick`'s own product; undefined when the pool table names no such pool. */
|
|
3999
|
+
readonly poolPick: (pool: string, directory: string) => PoolPickReport | undefined;
|
|
4000
|
+
/** The pool table's live names, so an unknown pool is refused naming the real ones rather than answered as an empty ranking. */
|
|
4001
|
+
readonly poolNames: () => readonly string[];
|
|
3943
4002
|
}
|
|
3944
4003
|
/** Builds the control-plane routers: one procedure per read, every one behind the control-token middleware. */
|
|
3945
4004
|
declare function createControlApiRouter(deps: ControlApiDeps): {
|
|
@@ -4441,13 +4500,13 @@ declare function createControlApiRouter(deps: ControlApiDeps): {
|
|
|
4441
4500
|
"config-profile": "config-profile";
|
|
4442
4501
|
identity: "identity";
|
|
4443
4502
|
provider: "provider";
|
|
4503
|
+
pool: "pool";
|
|
4504
|
+
keychain: "keychain";
|
|
4444
4505
|
"ambient-credential": "ambient-credential";
|
|
4445
4506
|
"binary-discovery": "binary-discovery";
|
|
4446
4507
|
"claude-shim": "claude-shim";
|
|
4447
4508
|
"path-resolution": "path-resolution";
|
|
4448
4509
|
"legacy-name": "legacy-name";
|
|
4449
|
-
pool: "pool";
|
|
4450
|
-
keychain: "keychain";
|
|
4451
4510
|
"directory-rules": "directory-rules";
|
|
4452
4511
|
"categories-local": "categories-local";
|
|
4453
4512
|
"active-identity": "active-identity";
|
|
@@ -4463,6 +4522,44 @@ declare function createControlApiRouter(deps: ControlApiDeps): {
|
|
|
4463
4522
|
}, zod_v4_core.$strict>>>;
|
|
4464
4523
|
}, zod_v4_core.$strict>, Record<never, never>, Record<never, never>>;
|
|
4465
4524
|
};
|
|
4525
|
+
pool: {
|
|
4526
|
+
pick: _orpc_server.DecoratedProcedure<_orpc_server.MergedInitialContext<DoorApiContext & Record<never, never>, DoorApiContext, DoorApiContext>, any, zod.ZodObject<{
|
|
4527
|
+
pool: zod.ZodString;
|
|
4528
|
+
path: zod.ZodString;
|
|
4529
|
+
}, zod_v4_core.$strict>, zod.ZodObject<{
|
|
4530
|
+
pool: zod.ZodString;
|
|
4531
|
+
directory: zod.ZodString;
|
|
4532
|
+
pick: zod.ZodOptional<zod.ZodString>;
|
|
4533
|
+
candidates: zod.ZodArray<zod.ZodObject<{
|
|
4534
|
+
identity: zod.ZodString;
|
|
4535
|
+
class: zod.ZodEnum<{
|
|
4536
|
+
unknown: "unknown";
|
|
4537
|
+
scored: "scored";
|
|
4538
|
+
"pay-per-use": "pay-per-use";
|
|
4539
|
+
ineligible: "ineligible";
|
|
4540
|
+
}>;
|
|
4541
|
+
score: zod.ZodOptional<zod.ZodNumber>;
|
|
4542
|
+
feasible: zod.ZodBoolean;
|
|
4543
|
+
blockedUntil: zod.ZodOptional<zod.ZodISODateTime>;
|
|
4544
|
+
plan: zod.ZodUnion<readonly [zod.ZodObject<{
|
|
4545
|
+
kind: zod.ZodLiteral<"subscription">;
|
|
4546
|
+
capacity: zod.ZodNumber;
|
|
4547
|
+
recognised: zod.ZodBoolean;
|
|
4548
|
+
tier: zod.ZodOptional<zod.ZodString>;
|
|
4549
|
+
}, zod_v4_core.$strict>, zod.ZodObject<{
|
|
4550
|
+
kind: zod.ZodLiteral<"pay-per-use">;
|
|
4551
|
+
tier: zod.ZodOptional<zod.ZodString>;
|
|
4552
|
+
}, zod_v4_core.$strict>]>;
|
|
4553
|
+
reasons: zod.ZodArray<zod.ZodString>;
|
|
4554
|
+
}, zod_v4_core.$strict>>;
|
|
4555
|
+
missing: zod.ZodArray<zod.ZodString>;
|
|
4556
|
+
earliestReturn: zod.ZodOptional<zod.ZodObject<{
|
|
4557
|
+
identity: zod.ZodString;
|
|
4558
|
+
at: zod.ZodISODateTime;
|
|
4559
|
+
}, zod_v4_core.$strict>>;
|
|
4560
|
+
stickyProblem: zod.ZodOptional<zod.ZodString>;
|
|
4561
|
+
}, zod_v4_core.$strict>, Record<never, never>, Record<never, never>>;
|
|
4562
|
+
};
|
|
4466
4563
|
};
|
|
4467
4564
|
/** The control-plane routers, as the merged mount's and the client's own types are derived from them. */
|
|
4468
4565
|
type ControlApiRouter = ReturnType<typeof createControlApiRouter>;
|
|
@@ -4976,13 +5073,13 @@ declare function createDoorApiRouter(deps: DoorApiDeps): {
|
|
|
4976
5073
|
"config-profile": "config-profile";
|
|
4977
5074
|
identity: "identity";
|
|
4978
5075
|
provider: "provider";
|
|
5076
|
+
pool: "pool";
|
|
5077
|
+
keychain: "keychain";
|
|
4979
5078
|
"ambient-credential": "ambient-credential";
|
|
4980
5079
|
"binary-discovery": "binary-discovery";
|
|
4981
5080
|
"claude-shim": "claude-shim";
|
|
4982
5081
|
"path-resolution": "path-resolution";
|
|
4983
5082
|
"legacy-name": "legacy-name";
|
|
4984
|
-
pool: "pool";
|
|
4985
|
-
keychain: "keychain";
|
|
4986
5083
|
"directory-rules": "directory-rules";
|
|
4987
5084
|
"categories-local": "categories-local";
|
|
4988
5085
|
"active-identity": "active-identity";
|
|
@@ -4998,6 +5095,44 @@ declare function createDoorApiRouter(deps: DoorApiDeps): {
|
|
|
4998
5095
|
}, zod_v4_core.$strict>>>;
|
|
4999
5096
|
}, zod_v4_core.$strict>, Record<never, never>, Record<never, never>>;
|
|
5000
5097
|
};
|
|
5098
|
+
pool: {
|
|
5099
|
+
pick: _orpc_server.DecoratedProcedure<_orpc_server.MergedInitialContext<DoorApiContext & Record<never, never>, DoorApiContext, DoorApiContext>, any, zod.ZodObject<{
|
|
5100
|
+
pool: zod.ZodString;
|
|
5101
|
+
path: zod.ZodString;
|
|
5102
|
+
}, zod_v4_core.$strict>, zod.ZodObject<{
|
|
5103
|
+
pool: zod.ZodString;
|
|
5104
|
+
directory: zod.ZodString;
|
|
5105
|
+
pick: zod.ZodOptional<zod.ZodString>;
|
|
5106
|
+
candidates: zod.ZodArray<zod.ZodObject<{
|
|
5107
|
+
identity: zod.ZodString;
|
|
5108
|
+
class: zod.ZodEnum<{
|
|
5109
|
+
unknown: "unknown";
|
|
5110
|
+
scored: "scored";
|
|
5111
|
+
"pay-per-use": "pay-per-use";
|
|
5112
|
+
ineligible: "ineligible";
|
|
5113
|
+
}>;
|
|
5114
|
+
score: zod.ZodOptional<zod.ZodNumber>;
|
|
5115
|
+
feasible: zod.ZodBoolean;
|
|
5116
|
+
blockedUntil: zod.ZodOptional<zod.ZodISODateTime>;
|
|
5117
|
+
plan: zod.ZodUnion<readonly [zod.ZodObject<{
|
|
5118
|
+
kind: zod.ZodLiteral<"subscription">;
|
|
5119
|
+
capacity: zod.ZodNumber;
|
|
5120
|
+
recognised: zod.ZodBoolean;
|
|
5121
|
+
tier: zod.ZodOptional<zod.ZodString>;
|
|
5122
|
+
}, zod_v4_core.$strict>, zod.ZodObject<{
|
|
5123
|
+
kind: zod.ZodLiteral<"pay-per-use">;
|
|
5124
|
+
tier: zod.ZodOptional<zod.ZodString>;
|
|
5125
|
+
}, zod_v4_core.$strict>]>;
|
|
5126
|
+
reasons: zod.ZodArray<zod.ZodString>;
|
|
5127
|
+
}, zod_v4_core.$strict>>;
|
|
5128
|
+
missing: zod.ZodArray<zod.ZodString>;
|
|
5129
|
+
earliestReturn: zod.ZodOptional<zod.ZodObject<{
|
|
5130
|
+
identity: zod.ZodString;
|
|
5131
|
+
at: zod.ZodISODateTime;
|
|
5132
|
+
}, zod_v4_core.$strict>>;
|
|
5133
|
+
stickyProblem: zod.ZodOptional<zod.ZodString>;
|
|
5134
|
+
}, zod_v4_core.$strict>, Record<never, never>, Record<never, never>>;
|
|
5135
|
+
};
|
|
5001
5136
|
rc: {
|
|
5002
5137
|
list: _orpc_server.DecoratedProcedure<_orpc_server.MergedInitialContext<DoorApiContext & Record<never, never>, DoorApiContext, DoorApiContext>, any, Schema<unknown, unknown>, zod.ZodObject<{
|
|
5003
5138
|
sessions: zod.ZodReadonly<zod.ZodArray<zod.ZodObject<{
|
|
@@ -5424,13 +5559,13 @@ declare const DoctorFindingSchema: z.ZodObject<{
|
|
|
5424
5559
|
"config-profile": "config-profile";
|
|
5425
5560
|
identity: "identity";
|
|
5426
5561
|
provider: "provider";
|
|
5562
|
+
pool: "pool";
|
|
5563
|
+
keychain: "keychain";
|
|
5427
5564
|
"ambient-credential": "ambient-credential";
|
|
5428
5565
|
"binary-discovery": "binary-discovery";
|
|
5429
5566
|
"claude-shim": "claude-shim";
|
|
5430
5567
|
"path-resolution": "path-resolution";
|
|
5431
5568
|
"legacy-name": "legacy-name";
|
|
5432
|
-
pool: "pool";
|
|
5433
|
-
keychain: "keychain";
|
|
5434
5569
|
"directory-rules": "directory-rules";
|
|
5435
5570
|
"categories-local": "categories-local";
|
|
5436
5571
|
"active-identity": "active-identity";
|
|
@@ -5453,13 +5588,13 @@ declare const DoctorRunOutputSchema: z.ZodObject<{
|
|
|
5453
5588
|
"config-profile": "config-profile";
|
|
5454
5589
|
identity: "identity";
|
|
5455
5590
|
provider: "provider";
|
|
5591
|
+
pool: "pool";
|
|
5592
|
+
keychain: "keychain";
|
|
5456
5593
|
"ambient-credential": "ambient-credential";
|
|
5457
5594
|
"binary-discovery": "binary-discovery";
|
|
5458
5595
|
"claude-shim": "claude-shim";
|
|
5459
5596
|
"path-resolution": "path-resolution";
|
|
5460
5597
|
"legacy-name": "legacy-name";
|
|
5461
|
-
pool: "pool";
|
|
5462
|
-
keychain: "keychain";
|
|
5463
5598
|
"directory-rules": "directory-rules";
|
|
5464
5599
|
"categories-local": "categories-local";
|
|
5465
5600
|
"active-identity": "active-identity";
|
|
@@ -5490,6 +5625,36 @@ interface LaunchEventPublisher {
|
|
|
5490
5625
|
/** Creates the launch lifecycle publisher. One per door process, fed by the supervisor's tick. */
|
|
5491
5626
|
declare function createLaunchEventPublisher(hub: DoorEventHub, now: () => number): LaunchEventPublisher;
|
|
5492
5627
|
|
|
5628
|
+
/**
|
|
5629
|
+
* The door health publisher: the supervisor's own state transitions as backbone events, so a consumer of the door learns the door itself changed and not only its sessions. The publisher emits nothing of its own: the supervisor tells it the moments it already lives through (every listener bound, a start failure that ends the generation, the idle shutdown), each published the moment it happens rather than at a tick, because these are process facts, not registry facts diffed between observations.
|
|
5630
|
+
*/
|
|
5631
|
+
/** Everything the door health publisher needs: the backbone it publishes on and the clock its events are observed at. */
|
|
5632
|
+
interface DoorHealthPublisher {
|
|
5633
|
+
/** Publishes the generation event: every listener bound, the state file naming this supervisor, the door fully serving. */
|
|
5634
|
+
readonly generation: (ports: {
|
|
5635
|
+
readonly providerPort: number;
|
|
5636
|
+
readonly connectPort: number;
|
|
5637
|
+
readonly directPort: number;
|
|
5638
|
+
}) => void;
|
|
5639
|
+
/** Publishes the start failure that ends the generation, naming which listener and why. */
|
|
5640
|
+
readonly listenerFailed: (listener: "provider" | "connect" | "direct", message: string) => void;
|
|
5641
|
+
/** Publishes the idle shutdown: the door closing itself with an empty session registry. */
|
|
5642
|
+
readonly idleShutdown: () => void;
|
|
5643
|
+
}
|
|
5644
|
+
/** Creates the door health publisher. One per door process, fed by the supervisor. */
|
|
5645
|
+
declare function createDoorHealthPublisher(hub: DoorEventHub, now: () => number, pid: number): DoorHealthPublisher;
|
|
5646
|
+
|
|
5647
|
+
/** Everything the expiring-quota publisher needs: the backbone (its usage source keeps the snapshots fresh), the snapshots as they stand at assembly, and the clock the tick reads. */
|
|
5648
|
+
interface QuotaExpiringPublisher {
|
|
5649
|
+
/** Checks every held window against the clock and publishes each one newly inside its final span. Idempotent within one span; cheap enough for the supervisor's every tick. */
|
|
5650
|
+
readonly check: () => void;
|
|
5651
|
+
}
|
|
5652
|
+
/** Creates the expiring-quota publisher. One per door process, checked on the supervisor's tick. */
|
|
5653
|
+
declare function createQuotaExpiringPublisher(hub: DoorEventHub, deps: {
|
|
5654
|
+
readonly seed: readonly UsageSnapshot[];
|
|
5655
|
+
readonly now: () => number;
|
|
5656
|
+
}): QuotaExpiringPublisher;
|
|
5657
|
+
|
|
5493
5658
|
/**
|
|
5494
5659
|
* The rate-limit facts one client read stream event carries, or undefined when the event is not a `rate_limit_event` this module can read: a payload of another type, a payload without the family's own one required field, or one whose `rate_limit_info` does not parse. An envelope the door cannot read is one it knows nothing about, never a failure, exactly as the stream's own parser treats an envelope it cannot read. Exported because the renderers (`frontdoor rc watch`, the web client's twin) narrow the same payload through the same one definition.
|
|
5495
5660
|
*/
|
|
@@ -5778,6 +5943,14 @@ interface FrontDoorSupervisorPorts {
|
|
|
5778
5943
|
* Reports one tick's session-registry facts to the door's event backbone: the sessions the tick's listing saw (taken before the prune, so a pruned launch's record is still there to name its start time) and the pids the tick's prune removed. The launch lifecycle publisher turns the diff between ticks into source-tagged events; the listing is also this loop's own idle input, so the two read one fact instead of two.
|
|
5779
5944
|
*/
|
|
5780
5945
|
readonly observeLaunchRegistry: (sessions: readonly FrontDoorSessionSummary[], pruned: readonly number[]) => void;
|
|
5946
|
+
/**
|
|
5947
|
+
* Publishes the supervisor's own state transitions to the door's event backbone: the generation serving, a start failure that ends it, the idle shutdown. Fed the moments the supervisor already lives through, published as they happen rather than at a tick, because these are process facts.
|
|
5948
|
+
*/
|
|
5949
|
+
readonly doorHealth: DoorHealthPublisher;
|
|
5950
|
+
/**
|
|
5951
|
+
* Checks the expiring-quota windows against the clock, once per tick: the publisher holds the snapshots the usage source keeps fresh, so this costs arithmetic, never a file read.
|
|
5952
|
+
*/
|
|
5953
|
+
readonly checkQuotaExpiry: () => void;
|
|
5781
5954
|
readonly log: (line: string) => void;
|
|
5782
5955
|
}
|
|
5783
5956
|
/** Options for `runFrontDoorSupervisor`. */
|
|
@@ -6516,5 +6689,5 @@ interface PrepareClaudeLaunchOptions {
|
|
|
6516
6689
|
*/
|
|
6517
6690
|
declare function prepareClaudeLaunch(options: PrepareClaudeLaunchOptions): LaunchPlan;
|
|
6518
6691
|
|
|
6519
|
-
export { AMBIENT_CREDENTIAL_VARS, CHECK_CREDENTIAL_APPLIES, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CheckReportJsonSchema, CheckRunInputSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DOOR_EVENT_BUFFER_EVENTS, DOOR_EVENT_SOURCE_RC, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, DoctorFindingSchema, DoctorRunOutputSchema, DoorEventSchema, DoorEventSourceQuerySchema, EXIT_FAILURE, EXIT_USAGE, EffectiveWindowSchema, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorSessionStatusSchema, FrontDoorSessionsOutputSchema, FrontDoorStartError, FrontDoorStateSchema, FrontDoorStatusOutputSchema, GlobalConfigSchema, HeadroomSocketTargetSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LAUNCH_EVENT_SOURCE, LaunchLifecycleEventSchema, LaunchRefusedError, LegacyProviderFileError, PROMPT_CACHE_TTL_MS, PlanClassSchema, PoolNameSchema, PoolNotFoundError, PoolPickReportSchema, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_CONTEXT_USAGE_DETAILS, RC_IDLE_EXPIRY_MS, RC_ORPC_PATH_PREFIX, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_READ_FILE_ENCODINGS, RC_REQUEST_PARSE_CAP_BYTES, RC_SELF_HOST_ENV, RC_SELF_HOST_KEEPALIVE_MS, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE, RC_SELF_HOST_RETENTION_MS, RC_SELF_HOST_SCOPE_LIST, RC_SELF_HOST_WORKER_JWT_TTL_SECONDS, RC_SESSIONS_PATH_PREFIX, RC_STREAM_BACKOFF_MS, RC_WEB_FETCH_ALLOW_PRIVATE_ENV, RC_WEB_FETCH_DEADLINE_MS, RC_WEB_FETCH_MAX_BYTES, RC_WEB_FETCH_MAX_REDIRECTS, ROUTED_PATH_PREFIX, RcLiveRateLimitSchema, RcPermissionModeSchema, RcRateLimitInfoSchema, RcRateLimitWindowSchema, RcStreamEnvelopeSchema, RcStreamEventSchema, UsageError, UsageListOutputSchema, UsageLiveOutputSchema, UsageSnapshotError, UsageSnapshotSchema, UsageWindowsInputSchema, UsageWindowsOutputSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, authenticateRcSessionMcpServer, buildEntryFacts, buildLayoutPaths, buildRcControlRequestPayload, buildRcControlResponsePayload, buildRcEndSessionPayload, buildRcEventWriteBody, buildRcFileSuggestionsPayload, buildRcGetContextUsagePayload, buildRcGetUsagePayload, buildRcInterruptPayload, buildRcKeepAlivePayload, buildRcMarkReadBody, buildRcMcpAuthenticatePayload, buildRcMcpOAuthCallbackUrlPayload, buildRcMcpReconnectPayload, buildRcMcpStatusPayload, buildRcReadFilePayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, collectFrontDoorStatus, collectPoolPick, createControlApiRouter, createDoorApiNodeHandler, createDoorApiRouter, createDoorEventHub, createEventsApiRouter, createLaunchEventPublisher, createLeafCache, createProfile, createRcApiNodeHandler, createRcApiRouter, createRcControlHandler, createRcCredentialStore, createRcEventFanout, createRcLiveUsage, createRcSelfHostSurface, createRcSessionTracker, createRcStreamHub, createSseParser, describeProviderEndpoint, detectAmbientCredential, doorApiAuth, doorApiNodeHandlerOf, effectiveWindow, endRcSession, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, evaluateWhen, fetchThroughWebProxy, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, formatFrontDoorStatus, forwardableHeaders, frontDoorApiClient, frontDoorApiLink, frontDoorRcApiClient, frontDoorRcControl, generateCa, getRcSessionContextUsage, getRcSessionMcpStatus, getRcSessionUsage, headroomSocketTarget, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isPrivateAddress, isRcContextUsageDetail, isRcPermissionMode, isRcReadFileEncoding, lateRcEventDial, lateRcStreamDial, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, matchBranch, mintLeaf, mintRcSelfHostCredential, observingRoutedRoute, parseConnectTarget, parseRcStreamEnvelope, planOf, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rankPool, rcEventWriteResultFromAnswer, rcFanoutOnDoorHub, rcObserverAsPassthrough, rcRateLimitInfoOf, rcSelfHostFromEnv, rcWebFetchAllowsPrivateFromEnv, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readRcSelfHostRecord, readRcSessionFile, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, realRcStreamDial, realRcWebFetch, reconnectRcSessionMcpServer, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runLauncher, runSupervisor, sendRcKeepAlive, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, spawnClaude, startConnectServer, submitRcSessionMcpOAuthCallbackUrl, suggestRcSessionFiles, teleportRcSession, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
|
|
6520
|
-
export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, Candidate, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CheckReportJson, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConditionContext, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectLocalSurface, ConnectServerConfig, ConnectServerHandle, ConnectTarget, ControlApiClient, ControlApiDeps, ControlApiRouter, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, DoorApiClient, DoorApiContext, DoorApiDeps, DoorApiRouter, DoorEvent, DoorEventHub, DoorEventPublisher, DoorEventStream, DoorEventsApiDeps, EffectiveWindow, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSessionStatus, FrontDoorStatus, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchEventPublisher, LaunchLifecycleEvent, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, NestedContribution, PlanClass, Pool, PoolMember, PoolPickReport, PoolRanking, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RankPoolInput, RcAnswerDecision, RcAnswerDeps, RcApiClient, RcApiDeps, RcApiRouter, RcContextUsageDetail, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcCredentialStore, RcDialAnswer, RcDialTarget, RcEventDial, RcEventFanout, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcLiveRateLimit, RcLiveUsage, RcLiveUsageDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcPresenceAnswer, RcRateLimitInfo, RcRateLimitWindow, RcReadFileEncoding, RcReadFileOptions, RcSelfHostCredentialRecord, RcSelfHostDeps, RcSelfHostMintResult, RcSelfHostSurface, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcStreamAnswer, RcStreamDial, RcStreamEnvelope, RcStreamEvent, RcStreamHub, RcStreamHubDeps, RcWebFetchDeps, RcWebFetchHop, RcWebFetchOutcome, RcWebFetcher, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunLauncherParams, RunSupervisorOptions, SpawnClaudeParams, SseParsedEvent, StickyPick, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition, WhenEvaluation };
|
|
6692
|
+
export { AMBIENT_CREDENTIAL_VARS, CHECK_CREDENTIAL_APPLIES, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CheckReportJsonSchema, CheckRunInputSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DOOR_EVENT_BUFFER_EVENTS, DOOR_EVENT_SOURCE_RC, DOOR_HEALTH_EVENT_SOURCE, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, DoctorFindingSchema, DoctorRunOutputSchema, DoorEventSchema, DoorEventSourceQuerySchema, DoorHealthEventSchema, EXIT_FAILURE, EXIT_USAGE, EffectiveWindowSchema, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorSessionStatusSchema, FrontDoorSessionsOutputSchema, FrontDoorStartError, FrontDoorStateSchema, FrontDoorStatusOutputSchema, GlobalConfigSchema, HeadroomSocketTargetSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LAUNCH_EVENT_SOURCE, LaunchLifecycleEventSchema, LaunchRefusedError, LegacyProviderFileError, PROMPT_CACHE_TTL_MS, PlanClassSchema, PoolNameSchema, PoolNotFoundError, PoolPickReportSchema, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, QUOTA_EXPIRING_EVENT_SOURCE, QuotaExpiringEventSchema, RC_CONTEXT_USAGE_DETAILS, RC_IDLE_EXPIRY_MS, RC_ORPC_PATH_PREFIX, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_READ_FILE_ENCODINGS, RC_REQUEST_PARSE_CAP_BYTES, RC_SELF_HOST_ENV, RC_SELF_HOST_KEEPALIVE_MS, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE, RC_SELF_HOST_RETENTION_MS, RC_SELF_HOST_SCOPE_LIST, RC_SELF_HOST_WORKER_JWT_TTL_SECONDS, RC_SESSIONS_PATH_PREFIX, RC_STREAM_BACKOFF_MS, RC_WEB_FETCH_ALLOW_PRIVATE_ENV, RC_WEB_FETCH_DEADLINE_MS, RC_WEB_FETCH_MAX_BYTES, RC_WEB_FETCH_MAX_REDIRECTS, ROUTED_PATH_PREFIX, RcLiveRateLimitSchema, RcPermissionModeSchema, RcRateLimitInfoSchema, RcRateLimitWindowSchema, RcStreamEnvelopeSchema, RcStreamEventSchema, USAGE_EVENT_SOURCE, UsageError, UsageListOutputSchema, UsageLiveOutputSchema, UsageSnapshotError, UsageSnapshotSchema, UsageWindowsInputSchema, UsageWindowsOutputSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, authenticateRcSessionMcpServer, buildEntryFacts, buildLayoutPaths, buildRcControlRequestPayload, buildRcControlResponsePayload, buildRcEndSessionPayload, buildRcEventWriteBody, buildRcFileSuggestionsPayload, buildRcGetContextUsagePayload, buildRcGetUsagePayload, buildRcInterruptPayload, buildRcKeepAlivePayload, buildRcMarkReadBody, buildRcMcpAuthenticatePayload, buildRcMcpOAuthCallbackUrlPayload, buildRcMcpReconnectPayload, buildRcMcpStatusPayload, buildRcReadFilePayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, collectFrontDoorStatus, collectPoolPick, createControlApiRouter, createDoorApiNodeHandler, createDoorApiRouter, createDoorEventHub, createDoorHealthPublisher, createEventsApiRouter, createLaunchEventPublisher, createLeafCache, createProfile, createQuotaExpiringPublisher, createRcApiNodeHandler, createRcApiRouter, createRcControlHandler, createRcCredentialStore, createRcEventFanout, createRcLiveUsage, createRcSelfHostSurface, createRcSessionTracker, createRcStreamHub, createSseParser, describeProviderEndpoint, detectAmbientCredential, doorApiAuth, doorApiNodeHandlerOf, effectiveWindow, endRcSession, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, evaluateWhen, fetchThroughWebProxy, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, formatFrontDoorStatus, forwardableHeaders, frontDoorApiClient, frontDoorApiLink, frontDoorRcApiClient, frontDoorRcControl, generateCa, getRcSessionContextUsage, getRcSessionMcpStatus, getRcSessionUsage, headroomSocketTarget, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isPrivateAddress, isRcContextUsageDetail, isRcPermissionMode, isRcReadFileEncoding, lateRcEventDial, lateRcStreamDial, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, matchBranch, mintLeaf, mintRcSelfHostCredential, observingRoutedRoute, parseConnectTarget, parseRcStreamEnvelope, planOf, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rankPool, rcEventWriteResultFromAnswer, rcFanoutOnDoorHub, rcObserverAsPassthrough, rcRateLimitInfoOf, rcSelfHostFromEnv, rcWebFetchAllowsPrivateFromEnv, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readRcSelfHostRecord, readRcSessionFile, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, realRcStreamDial, realRcWebFetch, reconnectRcSessionMcpServer, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runLauncher, runSupervisor, sendRcKeepAlive, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, spawnClaude, startConnectServer, submitRcSessionMcpOAuthCallbackUrl, suggestRcSessionFiles, teleportRcSession, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
|
|
6693
|
+
export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, Candidate, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CheckReportJson, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConditionContext, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectLocalSurface, ConnectServerConfig, ConnectServerHandle, ConnectTarget, ControlApiClient, ControlApiDeps, ControlApiRouter, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, DoorApiClient, DoorApiContext, DoorApiDeps, DoorApiRouter, DoorEvent, DoorEventHub, DoorEventPublisher, DoorEventStream, DoorEventsApiDeps, DoorHealthEvent, DoorHealthPublisher, EffectiveWindow, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSessionStatus, FrontDoorStatus, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchEventPublisher, LaunchLifecycleEvent, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, NestedContribution, PlanClass, Pool, PoolMember, PoolPickReport, PoolRanking, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, QuotaExpiringEvent, QuotaExpiringPublisher, RankPoolInput, RcAnswerDecision, RcAnswerDeps, RcApiClient, RcApiDeps, RcApiRouter, RcContextUsageDetail, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcCredentialStore, RcDialAnswer, RcDialTarget, RcEventDial, RcEventFanout, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcLiveRateLimit, RcLiveUsage, RcLiveUsageDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcPresenceAnswer, RcRateLimitInfo, RcRateLimitWindow, RcReadFileEncoding, RcReadFileOptions, RcSelfHostCredentialRecord, RcSelfHostDeps, RcSelfHostMintResult, RcSelfHostSurface, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcStreamAnswer, RcStreamDial, RcStreamEnvelope, RcStreamEvent, RcStreamHub, RcStreamHubDeps, RcWebFetchDeps, RcWebFetchHop, RcWebFetchOutcome, RcWebFetcher, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunLauncherParams, RunSupervisorOptions, SpawnClaudeParams, SseParsedEvent, StickyPick, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageChangeEvent, UsageReadFs, UsageSnapshot, WhenCondition, WhenEvaluation };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.31.0",
|
|
4
4
|
"description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joseph Mearman <joseph@mearman.co.uk>",
|