agent-shim 8.25.0 → 8.26.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 +349 -161
- package/dist/index.cjs +109 -16
- package/dist/index.mjs +103 -16
- package/dist/types/index.d.ts +271 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -114,11 +114,15 @@ __export(index_exports, {
|
|
|
114
114
|
RC_WEB_FETCH_MAX_BYTES: () => RC_WEB_FETCH_MAX_BYTES,
|
|
115
115
|
RC_WEB_FETCH_MAX_REDIRECTS: () => RC_WEB_FETCH_MAX_REDIRECTS,
|
|
116
116
|
ROUTED_PATH_PREFIX: () => ROUTED_PATH_PREFIX,
|
|
117
|
+
RcLiveRateLimitSchema: () => RcLiveRateLimitSchema,
|
|
117
118
|
RcPermissionModeSchema: () => RcPermissionModeSchema,
|
|
119
|
+
RcRateLimitInfoSchema: () => RcRateLimitInfoSchema,
|
|
120
|
+
RcRateLimitWindowSchema: () => RcRateLimitWindowSchema,
|
|
118
121
|
RcStreamEnvelopeSchema: () => RcStreamEnvelopeSchema,
|
|
119
122
|
RcStreamEventSchema: () => RcStreamEventSchema,
|
|
120
123
|
UsageError: () => UsageError,
|
|
121
124
|
UsageListOutputSchema: () => UsageListOutputSchema,
|
|
125
|
+
UsageLiveOutputSchema: () => UsageLiveOutputSchema,
|
|
122
126
|
UsageSnapshotError: () => UsageSnapshotError,
|
|
123
127
|
UsageSnapshotSchema: () => UsageSnapshotSchema,
|
|
124
128
|
UsageWindowsInputSchema: () => UsageWindowsInputSchema,
|
|
@@ -170,6 +174,7 @@ __export(index_exports, {
|
|
|
170
174
|
createRcControlHandler: () => createRcControlHandler,
|
|
171
175
|
createRcCredentialStore: () => createRcCredentialStore,
|
|
172
176
|
createRcEventFanout: () => createRcEventFanout,
|
|
177
|
+
createRcLiveUsage: () => createRcLiveUsage,
|
|
173
178
|
createRcSelfHostSurface: () => createRcSelfHostSurface,
|
|
174
179
|
createRcSessionTracker: () => createRcSessionTracker,
|
|
175
180
|
createRcStreamHub: () => createRcStreamHub,
|
|
@@ -231,6 +236,7 @@ __export(index_exports, {
|
|
|
231
236
|
rcEventWriteResultFromAnswer: () => rcEventWriteResultFromAnswer,
|
|
232
237
|
rcFanoutOnDoorHub: () => rcFanoutOnDoorHub,
|
|
233
238
|
rcObserverAsPassthrough: () => rcObserverAsPassthrough,
|
|
239
|
+
rcRateLimitInfoOf: () => rcRateLimitInfoOf,
|
|
234
240
|
rcSelfHostFromEnv: () => rcSelfHostFromEnv,
|
|
235
241
|
rcWebFetchAllowsPrivateFromEnv: () => rcWebFetchAllowsPrivateFromEnv,
|
|
236
242
|
readActiveIdentity: () => readActiveIdentity,
|
|
@@ -5373,6 +5379,35 @@ var RcStreamEventSchema = import_zod4.z.strictObject({
|
|
|
5373
5379
|
session: import_zod4.z.string(),
|
|
5374
5380
|
envelope: RcStreamEnvelopeSchema
|
|
5375
5381
|
});
|
|
5382
|
+
var RcRateLimitWindowSchema = import_zod4.z.looseObject({
|
|
5383
|
+
/** The fraction of the window used, usually between 0 and 1, above 1 when usage legitimately runs past the window's cap (the CLI's own field description states both). */
|
|
5384
|
+
utilization: import_zod4.z.number().optional(),
|
|
5385
|
+
/** When the window resets, in unix epoch seconds: the unit is the CLI's own field description, stated in the 2.1.289 bundle's schema. */
|
|
5386
|
+
resetsAt: import_zod4.z.number().optional()
|
|
5387
|
+
});
|
|
5388
|
+
var RcRateLimitInfoSchema = import_zod4.z.looseObject({
|
|
5389
|
+
/** The limiting window's own status (`allowed`, `allowed_warning`, `rejected`), asserted only as a string because the vocabulary grows with the CLI. */
|
|
5390
|
+
status: import_zod4.z.string(),
|
|
5391
|
+
/** When the limiting window resets, in unix epoch seconds. */
|
|
5392
|
+
resetsAt: import_zod4.z.number().optional(),
|
|
5393
|
+
/** Which window the top-level fields describe (`five_hour`, `seven_day`, and kin), the payload's own name for it. */
|
|
5394
|
+
rateLimitType: import_zod4.z.string().optional(),
|
|
5395
|
+
/** The fraction of the limiting window used, on the same scale the per-window utilizations carry. */
|
|
5396
|
+
utilization: import_zod4.z.number().optional(),
|
|
5397
|
+
/** Whether usage beyond the plan (extra usage) is currently covering the overflow, the payload's own flag for it. */
|
|
5398
|
+
isUsingOverage: import_zod4.z.boolean().optional(),
|
|
5399
|
+
/** The overage's own status, the same vocabulary the limiting window's `status` carries. */
|
|
5400
|
+
overageStatus: import_zod4.z.string().optional(),
|
|
5401
|
+
/** When the overage window resets, in unix epoch seconds. */
|
|
5402
|
+
overageResetsAt: import_zod4.z.number().optional(),
|
|
5403
|
+
/** Each subscription window the account's response headers carried: the session (five-hour), weekly (seven-day), and overage-included weekly windows, each present only when the account's responses carry it. */
|
|
5404
|
+
unifiedWindows: import_zod4.z.looseObject({ five_hour: RcRateLimitWindowSchema.optional(), seven_day: RcRateLimitWindowSchema.optional(), seven_day_overage_included: RcRateLimitWindowSchema.optional() }).optional()
|
|
5405
|
+
});
|
|
5406
|
+
var RcLiveRateLimitSchema = import_zod4.z.strictObject({
|
|
5407
|
+
session: import_zod4.z.string(),
|
|
5408
|
+
observedAt: import_zod4.z.number(),
|
|
5409
|
+
rateLimit: RcRateLimitInfoSchema
|
|
5410
|
+
});
|
|
5376
5411
|
var RcSessionQuerySchema = import_zod4.z.strictObject({
|
|
5377
5412
|
session: import_zod4.z.string().min(1).optional()
|
|
5378
5413
|
});
|
|
@@ -9983,6 +10018,12 @@ var UsageWindowsOutputSchema = import_zod19.z.strictObject({
|
|
|
9983
10018
|
fiveHour: EffectiveWindowSchema.optional(),
|
|
9984
10019
|
sevenDay: EffectiveWindowSchema.optional()
|
|
9985
10020
|
});
|
|
10021
|
+
var UsageLiveOutputSchema = import_zod19.z.strictObject({
|
|
10022
|
+
/** The freshest observation the door holds, never narrowed by the read's session filter because it is the door's single latest statement of the account's quota; absent while no rate_limit_event has been filed at all. */
|
|
10023
|
+
latest: RcLiveRateLimitSchema.optional(),
|
|
10024
|
+
/** One observation per session whose stream has filed a rate_limit_event this door generation. */
|
|
10025
|
+
sessions: import_zod19.z.readonly(import_zod19.z.array(RcLiveRateLimitSchema))
|
|
10026
|
+
});
|
|
9986
10027
|
var FrontDoorSessionStatusSchema = import_zod19.z.strictObject({
|
|
9987
10028
|
pid: import_zod19.z.int().positive(),
|
|
9988
10029
|
startedAt: import_zod19.z.number(),
|
|
@@ -10097,6 +10138,16 @@ function createControlApiRouter(deps) {
|
|
|
10097
10138
|
...unified?.fiveHour === void 0 ? {} : { fiveHour: effectiveWindow(unified.fiveHour, now) },
|
|
10098
10139
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
10099
10140
|
};
|
|
10141
|
+
}),
|
|
10142
|
+
live: authed.input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
|
|
10143
|
+
const sessions = deps.liveRateLimits(input.session);
|
|
10144
|
+
if (input.session !== void 0 && sessions.length === 0) {
|
|
10145
|
+
if (deps.list().some((session) => session.id === input.session)) {
|
|
10146
|
+
throw new import_client3.ORPCError("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
|
|
10147
|
+
}
|
|
10148
|
+
throw new import_client3.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
10149
|
+
}
|
|
10150
|
+
return { latest: deps.latestRateLimit(), sessions };
|
|
10100
10151
|
})
|
|
10101
10152
|
},
|
|
10102
10153
|
frontdoor: {
|
|
@@ -10317,6 +10368,42 @@ function createLaunchEventPublisher(hub, now) {
|
|
|
10317
10368
|
};
|
|
10318
10369
|
}
|
|
10319
10370
|
|
|
10371
|
+
// src/frontdoor/rcLiveUsage.ts
|
|
10372
|
+
var RC_RATE_LIMIT_EVENT_TYPE = "rate_limit_event";
|
|
10373
|
+
function isRecord5(value) {
|
|
10374
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10375
|
+
}
|
|
10376
|
+
function rcRateLimitInfoOf(event) {
|
|
10377
|
+
const payload = event.envelope.payload;
|
|
10378
|
+
if (!isRecord5(payload) || payload.type !== RC_RATE_LIMIT_EVENT_TYPE) {
|
|
10379
|
+
return void 0;
|
|
10380
|
+
}
|
|
10381
|
+
if (!isRecord5(payload.rate_limit_info)) {
|
|
10382
|
+
return void 0;
|
|
10383
|
+
}
|
|
10384
|
+
const parsed = RcRateLimitInfoSchema.safeParse(payload.rate_limit_info);
|
|
10385
|
+
return parsed.success ? parsed.data : void 0;
|
|
10386
|
+
}
|
|
10387
|
+
function createRcLiveUsage(deps) {
|
|
10388
|
+
const observed = /* @__PURE__ */ new Map();
|
|
10389
|
+
deps.hub.subscribe([DOOR_EVENT_SOURCE_RC], (event) => {
|
|
10390
|
+
const stream = RcStreamEventSchema.safeParse(event.payload);
|
|
10391
|
+
if (!stream.success) {
|
|
10392
|
+
return;
|
|
10393
|
+
}
|
|
10394
|
+
const rateLimit = rcRateLimitInfoOf(stream.data);
|
|
10395
|
+
if (rateLimit === void 0) {
|
|
10396
|
+
return;
|
|
10397
|
+
}
|
|
10398
|
+
observed.set(stream.data.session, { session: stream.data.session, observedAt: deps.now(), rateLimit });
|
|
10399
|
+
});
|
|
10400
|
+
const sorted = () => [...observed.values()].sort((left, right) => left.observedAt - right.observedAt || (left.session < right.session ? -1 : 1));
|
|
10401
|
+
return {
|
|
10402
|
+
liveOf: (sessionId) => sorted().filter((entry) => sessionId === void 0 || entry.session === sessionId),
|
|
10403
|
+
latestOf: () => sorted().at(-1)
|
|
10404
|
+
};
|
|
10405
|
+
}
|
|
10406
|
+
|
|
10320
10407
|
// src/frontdoor/rcStream.ts
|
|
10321
10408
|
var RC_STREAM_EVENT_NAME = "client_event";
|
|
10322
10409
|
var SSE_BYTE_ORDER_MARK = 65279;
|
|
@@ -10379,7 +10466,7 @@ function createSseParser() {
|
|
|
10379
10466
|
}
|
|
10380
10467
|
};
|
|
10381
10468
|
}
|
|
10382
|
-
function
|
|
10469
|
+
function isRecord6(value) {
|
|
10383
10470
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10384
10471
|
}
|
|
10385
10472
|
function sequenceNumOf(value) {
|
|
@@ -10401,7 +10488,7 @@ function parseRcStreamEnvelope(parsed) {
|
|
|
10401
10488
|
} catch {
|
|
10402
10489
|
return void 0;
|
|
10403
10490
|
}
|
|
10404
|
-
if (!
|
|
10491
|
+
if (!isRecord6(data)) {
|
|
10405
10492
|
return void 0;
|
|
10406
10493
|
}
|
|
10407
10494
|
const eventType = data.event_type;
|
|
@@ -10632,7 +10719,7 @@ function createRcStreamHub(deps) {
|
|
|
10632
10719
|
// src/frontdoor/rcSelfHostEndpoints.ts
|
|
10633
10720
|
var RC_SOURCE_WORKER = "worker";
|
|
10634
10721
|
var RC_SOURCE_CLIENT = "client";
|
|
10635
|
-
function
|
|
10722
|
+
function isRecord7(value) {
|
|
10636
10723
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10637
10724
|
}
|
|
10638
10725
|
function parseJsonObject2(body) {
|
|
@@ -10642,7 +10729,7 @@ function parseJsonObject2(body) {
|
|
|
10642
10729
|
} catch {
|
|
10643
10730
|
return void 0;
|
|
10644
10731
|
}
|
|
10645
|
-
return
|
|
10732
|
+
return isRecord7(parsed) ? parsed : void 0;
|
|
10646
10733
|
}
|
|
10647
10734
|
function nonEmptyString2(record, field) {
|
|
10648
10735
|
const value = record === void 0 ? void 0 : record[field];
|
|
@@ -10716,7 +10803,7 @@ async function serveRcClientChannels(ctx, tail, method, maxBatchEvents) {
|
|
|
10716
10803
|
}
|
|
10717
10804
|
const results = [];
|
|
10718
10805
|
for (const event of events) {
|
|
10719
|
-
if (!
|
|
10806
|
+
if (!isRecord7(event) || !isRecord7(event.payload)) {
|
|
10720
10807
|
await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "every event in a teleport write is an object carrying one payload object" } });
|
|
10721
10808
|
return true;
|
|
10722
10809
|
}
|
|
@@ -11086,7 +11173,7 @@ var RC_SELF_HOST_WORKER_EPOCH = 1;
|
|
|
11086
11173
|
var RC_STREAM_EVENT_NAME2 = "client_event";
|
|
11087
11174
|
var CONFLICT_REASON_HEADER2 = "x-ccr-conflict-reason";
|
|
11088
11175
|
var CONFLICT_REASON_EPOCH_STALE = "epoch_stale";
|
|
11089
|
-
function
|
|
11176
|
+
function isRecord8(value) {
|
|
11090
11177
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11091
11178
|
}
|
|
11092
11179
|
function isWebSearchRefusal(value) {
|
|
@@ -11170,7 +11257,7 @@ function parseJsonObject3(body) {
|
|
|
11170
11257
|
} catch {
|
|
11171
11258
|
return void 0;
|
|
11172
11259
|
}
|
|
11173
|
-
return
|
|
11260
|
+
return isRecord8(parsed) ? parsed : void 0;
|
|
11174
11261
|
}
|
|
11175
11262
|
function mintWorkerJwt(randomToken, issuedAt) {
|
|
11176
11263
|
const encode = (value) => Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
@@ -11417,7 +11504,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11417
11504
|
if (status !== void 0) {
|
|
11418
11505
|
session.workerStatus = status;
|
|
11419
11506
|
}
|
|
11420
|
-
if (
|
|
11507
|
+
if (isRecord8(body?.external_metadata)) {
|
|
11421
11508
|
session.externalMetadata = body.external_metadata;
|
|
11422
11509
|
}
|
|
11423
11510
|
await answerJson2(response, HTTP_STATUS.ok, {});
|
|
@@ -11447,7 +11534,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11447
11534
|
}
|
|
11448
11535
|
const results = [];
|
|
11449
11536
|
for (const event of events) {
|
|
11450
|
-
if (!
|
|
11537
|
+
if (!isRecord8(event) || !isRecord8(event.payload)) {
|
|
11451
11538
|
await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "every event in a batch is an object carrying one payload object" } });
|
|
11452
11539
|
return;
|
|
11453
11540
|
}
|
|
@@ -11480,7 +11567,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11480
11567
|
return;
|
|
11481
11568
|
}
|
|
11482
11569
|
for (const event of events) {
|
|
11483
|
-
if (
|
|
11570
|
+
if (isRecord8(event)) {
|
|
11484
11571
|
session.internalEvents.push({ eventId: deps.newUuid(), body: event });
|
|
11485
11572
|
}
|
|
11486
11573
|
}
|
|
@@ -11576,7 +11663,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11576
11663
|
}
|
|
11577
11664
|
const results = [];
|
|
11578
11665
|
for (const event of events) {
|
|
11579
|
-
if (!
|
|
11666
|
+
if (!isRecord8(event) || !isRecord8(event.payload)) {
|
|
11580
11667
|
await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "every event in a write is an object carrying one payload object" } });
|
|
11581
11668
|
return;
|
|
11582
11669
|
}
|
|
@@ -11770,7 +11857,7 @@ var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
|
|
|
11770
11857
|
var RC_SELF_HOST_RECORD_FILE = "credential.json";
|
|
11771
11858
|
var SELF_HOST_EMAIL = "selfhost@agent-shim.invalid";
|
|
11772
11859
|
var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
11773
|
-
function
|
|
11860
|
+
function isRecord9(value) {
|
|
11774
11861
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11775
11862
|
}
|
|
11776
11863
|
function readJsonObject(fs12, file) {
|
|
@@ -11784,7 +11871,7 @@ function readJsonObject(fs12, file) {
|
|
|
11784
11871
|
} catch {
|
|
11785
11872
|
return void 0;
|
|
11786
11873
|
}
|
|
11787
|
-
return
|
|
11874
|
+
return isRecord9(parsed) ? parsed : void 0;
|
|
11788
11875
|
}
|
|
11789
11876
|
function readRcSelfHostRecord(fs12, frontdoorDir) {
|
|
11790
11877
|
const parsed = readJsonObject(fs12, import_node_path28.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
@@ -11808,7 +11895,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
11808
11895
|
const recordFile = import_node_path28.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
11809
11896
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
11810
11897
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
11811
|
-
const existingOauth =
|
|
11898
|
+
const existingOauth = isRecord9(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
11812
11899
|
const existingToken = typeof existingOauth?.accessToken === "string" && existingOauth.accessToken !== "" ? existingOauth.accessToken : void 0;
|
|
11813
11900
|
const existingIsOwn = existingToken !== void 0 && previousRecord?.accessToken === existingToken;
|
|
11814
11901
|
if (existingToken !== void 0 && !existingIsOwn && !deps.force) {
|
|
@@ -11825,7 +11912,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
11825
11912
|
deps.fs.writeFilePrivate(credentialsFile, `${JSON.stringify({ ...existingCredentials, claudeAiOauth: { accessToken, refreshToken, expiresAt: null, scopes: [...RC_SELF_HOST_SCOPE_LIST], subscriptionType: SELF_HOST_SUBSCRIPTION_TYPE, rateLimitTier: null } }, null, 2)}
|
|
11826
11913
|
`);
|
|
11827
11914
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
11828
|
-
const existingBlock = (value) =>
|
|
11915
|
+
const existingBlock = (value) => isRecord9(value) ? value : {};
|
|
11829
11916
|
deps.fs.writeFilePrivate(claudeJsonFile, `${JSON.stringify({
|
|
11830
11917
|
...claudeJson,
|
|
11831
11918
|
oauthAccount: {
|
|
@@ -12024,7 +12111,7 @@ var import_node_path30 = __toESM(require("node:path"), 1);
|
|
|
12024
12111
|
// package.json
|
|
12025
12112
|
var package_default = {
|
|
12026
12113
|
name: "agent-shim",
|
|
12027
|
-
version: "8.
|
|
12114
|
+
version: "8.26.0",
|
|
12028
12115
|
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.",
|
|
12029
12116
|
license: "MIT",
|
|
12030
12117
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -13288,11 +13375,15 @@ function prepareClaudeLaunch(options) {
|
|
|
13288
13375
|
RC_WEB_FETCH_MAX_BYTES,
|
|
13289
13376
|
RC_WEB_FETCH_MAX_REDIRECTS,
|
|
13290
13377
|
ROUTED_PATH_PREFIX,
|
|
13378
|
+
RcLiveRateLimitSchema,
|
|
13291
13379
|
RcPermissionModeSchema,
|
|
13380
|
+
RcRateLimitInfoSchema,
|
|
13381
|
+
RcRateLimitWindowSchema,
|
|
13292
13382
|
RcStreamEnvelopeSchema,
|
|
13293
13383
|
RcStreamEventSchema,
|
|
13294
13384
|
UsageError,
|
|
13295
13385
|
UsageListOutputSchema,
|
|
13386
|
+
UsageLiveOutputSchema,
|
|
13296
13387
|
UsageSnapshotError,
|
|
13297
13388
|
UsageSnapshotSchema,
|
|
13298
13389
|
UsageWindowsInputSchema,
|
|
@@ -13344,6 +13435,7 @@ function prepareClaudeLaunch(options) {
|
|
|
13344
13435
|
createRcControlHandler,
|
|
13345
13436
|
createRcCredentialStore,
|
|
13346
13437
|
createRcEventFanout,
|
|
13438
|
+
createRcLiveUsage,
|
|
13347
13439
|
createRcSelfHostSurface,
|
|
13348
13440
|
createRcSessionTracker,
|
|
13349
13441
|
createRcStreamHub,
|
|
@@ -13405,6 +13497,7 @@ function prepareClaudeLaunch(options) {
|
|
|
13405
13497
|
rcEventWriteResultFromAnswer,
|
|
13406
13498
|
rcFanoutOnDoorHub,
|
|
13407
13499
|
rcObserverAsPassthrough,
|
|
13500
|
+
rcRateLimitInfoOf,
|
|
13408
13501
|
rcSelfHostFromEnv,
|
|
13409
13502
|
rcWebFetchAllowsPrivateFromEnv,
|
|
13410
13503
|
readActiveIdentity,
|
package/dist/index.mjs
CHANGED
|
@@ -5074,6 +5074,35 @@ var RcStreamEventSchema = z4.strictObject({
|
|
|
5074
5074
|
session: z4.string(),
|
|
5075
5075
|
envelope: RcStreamEnvelopeSchema
|
|
5076
5076
|
});
|
|
5077
|
+
var RcRateLimitWindowSchema = z4.looseObject({
|
|
5078
|
+
/** The fraction of the window used, usually between 0 and 1, above 1 when usage legitimately runs past the window's cap (the CLI's own field description states both). */
|
|
5079
|
+
utilization: z4.number().optional(),
|
|
5080
|
+
/** When the window resets, in unix epoch seconds: the unit is the CLI's own field description, stated in the 2.1.289 bundle's schema. */
|
|
5081
|
+
resetsAt: z4.number().optional()
|
|
5082
|
+
});
|
|
5083
|
+
var RcRateLimitInfoSchema = z4.looseObject({
|
|
5084
|
+
/** The limiting window's own status (`allowed`, `allowed_warning`, `rejected`), asserted only as a string because the vocabulary grows with the CLI. */
|
|
5085
|
+
status: z4.string(),
|
|
5086
|
+
/** When the limiting window resets, in unix epoch seconds. */
|
|
5087
|
+
resetsAt: z4.number().optional(),
|
|
5088
|
+
/** Which window the top-level fields describe (`five_hour`, `seven_day`, and kin), the payload's own name for it. */
|
|
5089
|
+
rateLimitType: z4.string().optional(),
|
|
5090
|
+
/** The fraction of the limiting window used, on the same scale the per-window utilizations carry. */
|
|
5091
|
+
utilization: z4.number().optional(),
|
|
5092
|
+
/** Whether usage beyond the plan (extra usage) is currently covering the overflow, the payload's own flag for it. */
|
|
5093
|
+
isUsingOverage: z4.boolean().optional(),
|
|
5094
|
+
/** The overage's own status, the same vocabulary the limiting window's `status` carries. */
|
|
5095
|
+
overageStatus: z4.string().optional(),
|
|
5096
|
+
/** When the overage window resets, in unix epoch seconds. */
|
|
5097
|
+
overageResetsAt: z4.number().optional(),
|
|
5098
|
+
/** Each subscription window the account's response headers carried: the session (five-hour), weekly (seven-day), and overage-included weekly windows, each present only when the account's responses carry it. */
|
|
5099
|
+
unifiedWindows: z4.looseObject({ five_hour: RcRateLimitWindowSchema.optional(), seven_day: RcRateLimitWindowSchema.optional(), seven_day_overage_included: RcRateLimitWindowSchema.optional() }).optional()
|
|
5100
|
+
});
|
|
5101
|
+
var RcLiveRateLimitSchema = z4.strictObject({
|
|
5102
|
+
session: z4.string(),
|
|
5103
|
+
observedAt: z4.number(),
|
|
5104
|
+
rateLimit: RcRateLimitInfoSchema
|
|
5105
|
+
});
|
|
5077
5106
|
var RcSessionQuerySchema = z4.strictObject({
|
|
5078
5107
|
session: z4.string().min(1).optional()
|
|
5079
5108
|
});
|
|
@@ -9684,6 +9713,12 @@ var UsageWindowsOutputSchema = z19.strictObject({
|
|
|
9684
9713
|
fiveHour: EffectiveWindowSchema.optional(),
|
|
9685
9714
|
sevenDay: EffectiveWindowSchema.optional()
|
|
9686
9715
|
});
|
|
9716
|
+
var UsageLiveOutputSchema = z19.strictObject({
|
|
9717
|
+
/** The freshest observation the door holds, never narrowed by the read's session filter because it is the door's single latest statement of the account's quota; absent while no rate_limit_event has been filed at all. */
|
|
9718
|
+
latest: RcLiveRateLimitSchema.optional(),
|
|
9719
|
+
/** One observation per session whose stream has filed a rate_limit_event this door generation. */
|
|
9720
|
+
sessions: z19.readonly(z19.array(RcLiveRateLimitSchema))
|
|
9721
|
+
});
|
|
9687
9722
|
var FrontDoorSessionStatusSchema = z19.strictObject({
|
|
9688
9723
|
pid: z19.int().positive(),
|
|
9689
9724
|
startedAt: z19.number(),
|
|
@@ -9798,6 +9833,16 @@ function createControlApiRouter(deps) {
|
|
|
9798
9833
|
...unified?.fiveHour === void 0 ? {} : { fiveHour: effectiveWindow(unified.fiveHour, now) },
|
|
9799
9834
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
9800
9835
|
};
|
|
9836
|
+
}),
|
|
9837
|
+
live: authed.input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
|
|
9838
|
+
const sessions = deps.liveRateLimits(input.session);
|
|
9839
|
+
if (input.session !== void 0 && sessions.length === 0) {
|
|
9840
|
+
if (deps.list().some((session) => session.id === input.session)) {
|
|
9841
|
+
throw new ORPCError3("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
|
|
9842
|
+
}
|
|
9843
|
+
throw new ORPCError3("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
9844
|
+
}
|
|
9845
|
+
return { latest: deps.latestRateLimit(), sessions };
|
|
9801
9846
|
})
|
|
9802
9847
|
},
|
|
9803
9848
|
frontdoor: {
|
|
@@ -10018,6 +10063,42 @@ function createLaunchEventPublisher(hub, now) {
|
|
|
10018
10063
|
};
|
|
10019
10064
|
}
|
|
10020
10065
|
|
|
10066
|
+
// src/frontdoor/rcLiveUsage.ts
|
|
10067
|
+
var RC_RATE_LIMIT_EVENT_TYPE = "rate_limit_event";
|
|
10068
|
+
function isRecord5(value) {
|
|
10069
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10070
|
+
}
|
|
10071
|
+
function rcRateLimitInfoOf(event) {
|
|
10072
|
+
const payload = event.envelope.payload;
|
|
10073
|
+
if (!isRecord5(payload) || payload.type !== RC_RATE_LIMIT_EVENT_TYPE) {
|
|
10074
|
+
return void 0;
|
|
10075
|
+
}
|
|
10076
|
+
if (!isRecord5(payload.rate_limit_info)) {
|
|
10077
|
+
return void 0;
|
|
10078
|
+
}
|
|
10079
|
+
const parsed = RcRateLimitInfoSchema.safeParse(payload.rate_limit_info);
|
|
10080
|
+
return parsed.success ? parsed.data : void 0;
|
|
10081
|
+
}
|
|
10082
|
+
function createRcLiveUsage(deps) {
|
|
10083
|
+
const observed = /* @__PURE__ */ new Map();
|
|
10084
|
+
deps.hub.subscribe([DOOR_EVENT_SOURCE_RC], (event) => {
|
|
10085
|
+
const stream = RcStreamEventSchema.safeParse(event.payload);
|
|
10086
|
+
if (!stream.success) {
|
|
10087
|
+
return;
|
|
10088
|
+
}
|
|
10089
|
+
const rateLimit = rcRateLimitInfoOf(stream.data);
|
|
10090
|
+
if (rateLimit === void 0) {
|
|
10091
|
+
return;
|
|
10092
|
+
}
|
|
10093
|
+
observed.set(stream.data.session, { session: stream.data.session, observedAt: deps.now(), rateLimit });
|
|
10094
|
+
});
|
|
10095
|
+
const sorted = () => [...observed.values()].sort((left, right) => left.observedAt - right.observedAt || (left.session < right.session ? -1 : 1));
|
|
10096
|
+
return {
|
|
10097
|
+
liveOf: (sessionId) => sorted().filter((entry) => sessionId === void 0 || entry.session === sessionId),
|
|
10098
|
+
latestOf: () => sorted().at(-1)
|
|
10099
|
+
};
|
|
10100
|
+
}
|
|
10101
|
+
|
|
10021
10102
|
// src/frontdoor/rcStream.ts
|
|
10022
10103
|
var RC_STREAM_EVENT_NAME = "client_event";
|
|
10023
10104
|
var SSE_BYTE_ORDER_MARK = 65279;
|
|
@@ -10080,7 +10161,7 @@ function createSseParser() {
|
|
|
10080
10161
|
}
|
|
10081
10162
|
};
|
|
10082
10163
|
}
|
|
10083
|
-
function
|
|
10164
|
+
function isRecord6(value) {
|
|
10084
10165
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10085
10166
|
}
|
|
10086
10167
|
function sequenceNumOf(value) {
|
|
@@ -10102,7 +10183,7 @@ function parseRcStreamEnvelope(parsed) {
|
|
|
10102
10183
|
} catch {
|
|
10103
10184
|
return void 0;
|
|
10104
10185
|
}
|
|
10105
|
-
if (!
|
|
10186
|
+
if (!isRecord6(data)) {
|
|
10106
10187
|
return void 0;
|
|
10107
10188
|
}
|
|
10108
10189
|
const eventType = data.event_type;
|
|
@@ -10333,7 +10414,7 @@ function createRcStreamHub(deps) {
|
|
|
10333
10414
|
// src/frontdoor/rcSelfHostEndpoints.ts
|
|
10334
10415
|
var RC_SOURCE_WORKER = "worker";
|
|
10335
10416
|
var RC_SOURCE_CLIENT = "client";
|
|
10336
|
-
function
|
|
10417
|
+
function isRecord7(value) {
|
|
10337
10418
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10338
10419
|
}
|
|
10339
10420
|
function parseJsonObject2(body) {
|
|
@@ -10343,7 +10424,7 @@ function parseJsonObject2(body) {
|
|
|
10343
10424
|
} catch {
|
|
10344
10425
|
return void 0;
|
|
10345
10426
|
}
|
|
10346
|
-
return
|
|
10427
|
+
return isRecord7(parsed) ? parsed : void 0;
|
|
10347
10428
|
}
|
|
10348
10429
|
function nonEmptyString2(record, field) {
|
|
10349
10430
|
const value = record === void 0 ? void 0 : record[field];
|
|
@@ -10417,7 +10498,7 @@ async function serveRcClientChannels(ctx, tail, method, maxBatchEvents) {
|
|
|
10417
10498
|
}
|
|
10418
10499
|
const results = [];
|
|
10419
10500
|
for (const event of events) {
|
|
10420
|
-
if (!
|
|
10501
|
+
if (!isRecord7(event) || !isRecord7(event.payload)) {
|
|
10421
10502
|
await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "every event in a teleport write is an object carrying one payload object" } });
|
|
10422
10503
|
return true;
|
|
10423
10504
|
}
|
|
@@ -10787,7 +10868,7 @@ var RC_SELF_HOST_WORKER_EPOCH = 1;
|
|
|
10787
10868
|
var RC_STREAM_EVENT_NAME2 = "client_event";
|
|
10788
10869
|
var CONFLICT_REASON_HEADER2 = "x-ccr-conflict-reason";
|
|
10789
10870
|
var CONFLICT_REASON_EPOCH_STALE = "epoch_stale";
|
|
10790
|
-
function
|
|
10871
|
+
function isRecord8(value) {
|
|
10791
10872
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10792
10873
|
}
|
|
10793
10874
|
function isWebSearchRefusal(value) {
|
|
@@ -10871,7 +10952,7 @@ function parseJsonObject3(body) {
|
|
|
10871
10952
|
} catch {
|
|
10872
10953
|
return void 0;
|
|
10873
10954
|
}
|
|
10874
|
-
return
|
|
10955
|
+
return isRecord8(parsed) ? parsed : void 0;
|
|
10875
10956
|
}
|
|
10876
10957
|
function mintWorkerJwt(randomToken, issuedAt) {
|
|
10877
10958
|
const encode = (value) => Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
@@ -11118,7 +11199,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11118
11199
|
if (status !== void 0) {
|
|
11119
11200
|
session.workerStatus = status;
|
|
11120
11201
|
}
|
|
11121
|
-
if (
|
|
11202
|
+
if (isRecord8(body?.external_metadata)) {
|
|
11122
11203
|
session.externalMetadata = body.external_metadata;
|
|
11123
11204
|
}
|
|
11124
11205
|
await answerJson2(response, HTTP_STATUS.ok, {});
|
|
@@ -11148,7 +11229,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11148
11229
|
}
|
|
11149
11230
|
const results = [];
|
|
11150
11231
|
for (const event of events) {
|
|
11151
|
-
if (!
|
|
11232
|
+
if (!isRecord8(event) || !isRecord8(event.payload)) {
|
|
11152
11233
|
await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "every event in a batch is an object carrying one payload object" } });
|
|
11153
11234
|
return;
|
|
11154
11235
|
}
|
|
@@ -11181,7 +11262,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11181
11262
|
return;
|
|
11182
11263
|
}
|
|
11183
11264
|
for (const event of events) {
|
|
11184
|
-
if (
|
|
11265
|
+
if (isRecord8(event)) {
|
|
11185
11266
|
session.internalEvents.push({ eventId: deps.newUuid(), body: event });
|
|
11186
11267
|
}
|
|
11187
11268
|
}
|
|
@@ -11277,7 +11358,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
11277
11358
|
}
|
|
11278
11359
|
const results = [];
|
|
11279
11360
|
for (const event of events) {
|
|
11280
|
-
if (!
|
|
11361
|
+
if (!isRecord8(event) || !isRecord8(event.payload)) {
|
|
11281
11362
|
await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "every event in a write is an object carrying one payload object" } });
|
|
11282
11363
|
return;
|
|
11283
11364
|
}
|
|
@@ -11471,7 +11552,7 @@ var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
|
|
|
11471
11552
|
var RC_SELF_HOST_RECORD_FILE = "credential.json";
|
|
11472
11553
|
var SELF_HOST_EMAIL = "selfhost@agent-shim.invalid";
|
|
11473
11554
|
var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
11474
|
-
function
|
|
11555
|
+
function isRecord9(value) {
|
|
11475
11556
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11476
11557
|
}
|
|
11477
11558
|
function readJsonObject(fs12, file) {
|
|
@@ -11485,7 +11566,7 @@ function readJsonObject(fs12, file) {
|
|
|
11485
11566
|
} catch {
|
|
11486
11567
|
return void 0;
|
|
11487
11568
|
}
|
|
11488
|
-
return
|
|
11569
|
+
return isRecord9(parsed) ? parsed : void 0;
|
|
11489
11570
|
}
|
|
11490
11571
|
function readRcSelfHostRecord(fs12, frontdoorDir) {
|
|
11491
11572
|
const parsed = readJsonObject(fs12, path28.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
@@ -11509,7 +11590,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
11509
11590
|
const recordFile = path28.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
11510
11591
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
11511
11592
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
11512
|
-
const existingOauth =
|
|
11593
|
+
const existingOauth = isRecord9(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
11513
11594
|
const existingToken = typeof existingOauth?.accessToken === "string" && existingOauth.accessToken !== "" ? existingOauth.accessToken : void 0;
|
|
11514
11595
|
const existingIsOwn = existingToken !== void 0 && previousRecord?.accessToken === existingToken;
|
|
11515
11596
|
if (existingToken !== void 0 && !existingIsOwn && !deps.force) {
|
|
@@ -11526,7 +11607,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
11526
11607
|
deps.fs.writeFilePrivate(credentialsFile, `${JSON.stringify({ ...existingCredentials, claudeAiOauth: { accessToken, refreshToken, expiresAt: null, scopes: [...RC_SELF_HOST_SCOPE_LIST], subscriptionType: SELF_HOST_SUBSCRIPTION_TYPE, rateLimitTier: null } }, null, 2)}
|
|
11527
11608
|
`);
|
|
11528
11609
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
11529
|
-
const existingBlock = (value) =>
|
|
11610
|
+
const existingBlock = (value) => isRecord9(value) ? value : {};
|
|
11530
11611
|
deps.fs.writeFilePrivate(claudeJsonFile, `${JSON.stringify({
|
|
11531
11612
|
...claudeJson,
|
|
11532
11613
|
oauthAccount: {
|
|
@@ -11725,7 +11806,7 @@ import path30 from "node:path";
|
|
|
11725
11806
|
// package.json
|
|
11726
11807
|
var package_default = {
|
|
11727
11808
|
name: "agent-shim",
|
|
11728
|
-
version: "8.
|
|
11809
|
+
version: "8.26.0",
|
|
11729
11810
|
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.",
|
|
11730
11811
|
license: "MIT",
|
|
11731
11812
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -12988,11 +13069,15 @@ export {
|
|
|
12988
13069
|
RC_WEB_FETCH_MAX_BYTES,
|
|
12989
13070
|
RC_WEB_FETCH_MAX_REDIRECTS,
|
|
12990
13071
|
ROUTED_PATH_PREFIX,
|
|
13072
|
+
RcLiveRateLimitSchema,
|
|
12991
13073
|
RcPermissionModeSchema,
|
|
13074
|
+
RcRateLimitInfoSchema,
|
|
13075
|
+
RcRateLimitWindowSchema,
|
|
12992
13076
|
RcStreamEnvelopeSchema,
|
|
12993
13077
|
RcStreamEventSchema,
|
|
12994
13078
|
UsageError,
|
|
12995
13079
|
UsageListOutputSchema,
|
|
13080
|
+
UsageLiveOutputSchema,
|
|
12996
13081
|
UsageSnapshotError,
|
|
12997
13082
|
UsageSnapshotSchema,
|
|
12998
13083
|
UsageWindowsInputSchema,
|
|
@@ -13044,6 +13129,7 @@ export {
|
|
|
13044
13129
|
createRcControlHandler,
|
|
13045
13130
|
createRcCredentialStore,
|
|
13046
13131
|
createRcEventFanout,
|
|
13132
|
+
createRcLiveUsage,
|
|
13047
13133
|
createRcSelfHostSurface,
|
|
13048
13134
|
createRcSessionTracker,
|
|
13049
13135
|
createRcStreamHub,
|
|
@@ -13105,6 +13191,7 @@ export {
|
|
|
13105
13191
|
rcEventWriteResultFromAnswer,
|
|
13106
13192
|
rcFanoutOnDoorHub,
|
|
13107
13193
|
rcObserverAsPassthrough,
|
|
13194
|
+
rcRateLimitInfoOf,
|
|
13108
13195
|
rcSelfHostFromEnv,
|
|
13109
13196
|
rcWebFetchAllowsPrivateFromEnv,
|
|
13110
13197
|
readActiveIdentity,
|