agent-shim 8.24.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 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.24.0",
61799
+ version: "8.26.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>",
@@ -66142,13 +66142,6 @@ var https3 = __toESM(require("node:https"), 1);
66142
66142
  var net2 = __toESM(require("node:net"), 1);
66143
66143
  var tls = __toESM(require("node:tls"), 1);
66144
66144
 
66145
- // src/frontdoor/server.ts
66146
- var import_node_http2 = __toESM(require("node:http"), 1);
66147
- var import_node_https = __toESM(require("node:https"), 1);
66148
-
66149
- // src/frontdoor/rcControl.ts
66150
- var https = __toESM(require("node:https"), 1);
66151
-
66152
66145
  // src/frontdoor/rcSessions.ts
66153
66146
  var RC_SESSIONS_PATH_PREFIX = "/v1/code/sessions";
66154
66147
  var RC_SESSION_ID_PREFIX = "cse_";
@@ -66725,7 +66718,7 @@ async function answerRcControlRequest(deps, sessionId, requestId, decision) {
66725
66718
  }
66726
66719
  return result;
66727
66720
  }
66728
- async function deliverRcClientPayload(deps, sessionId, payload, action) {
66721
+ async function deliverRcClientPayload(deps, sessionId, payload, action, to = "events") {
66729
66722
  const credential = deps.credentialOf(sessionId);
66730
66723
  if (credential === void 0) {
66731
66724
  return { ok: false, message: rcSessionNotObservedMessage(sessionId) };
@@ -66736,7 +66729,7 @@ async function deliverRcClientPayload(deps, sessionId, payload, action) {
66736
66729
  const body = JSON.stringify(buildRcEventWriteBody(payload));
66737
66730
  let answer;
66738
66731
  try {
66739
- answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
66732
+ answer = await (to === "teleport-events" ? deps.dial.writeTeleportEvents(sessionId, rcWriteHeaders(credential), body) : deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body));
66740
66733
  } catch (error62) {
66741
66734
  return { ok: false, message: `the door could not reach the API host to ${action}: ${error62 instanceof Error ? error62.message : String(error62)}` };
66742
66735
  }
@@ -66830,8 +66823,22 @@ async function submitRcSessionMcpOAuthCallbackUrl(deps, sessionId, serverName, c
66830
66823
  async function sendRcKeepAlive(deps, sessionId) {
66831
66824
  return await deliverRcClientPayload(deps, sessionId, buildRcKeepAlivePayload(), `keep session ${sessionId} alive`);
66832
66825
  }
66826
+ async function teleportRcSession(deps, sessionId, marker) {
66827
+ if (marker === "") {
66828
+ return { ok: false, message: "a teleport write needs a non-empty marker: the teleport relay anchors on a marker line's uuid and string content, and an empty string carries neither" };
66829
+ }
66830
+ return await deliverRcClientPayload(deps, sessionId, buildRcUserMessagePayload(deps.newUuid(), sessionId, marker), `teleport a marker into session ${sessionId}`, "teleport-events");
66831
+ }
66832
+ function buildRcMarkReadBody(eventId) {
66833
+ return eventId === void 0 ? {} : { event_id: eventId };
66834
+ }
66835
+
66836
+ // src/frontdoor/server.ts
66837
+ var import_node_http2 = __toESM(require("node:http"), 1);
66838
+ var import_node_https = __toESM(require("node:https"), 1);
66833
66839
 
66834
66840
  // src/frontdoor/rcControl.ts
66841
+ var https = __toESM(require("node:https"), 1);
66835
66842
  var RC_PERMISSION_MODE_LIST = RC_PERMISSION_MODES.join(", ");
66836
66843
  var CONTROL_PATH_PREFIX = "/__agent-shim/rc";
66837
66844
  var CONTROL_BODY_CAP_BYTES = 10485760;
@@ -67005,6 +67012,15 @@ function createRcControlHandler(deps) {
67005
67012
  const callbackUrl = bodyString(body, "callbackUrl");
67006
67013
  return session === void 0 || serverName === void 0 || callbackUrl === void 0 ? { error: "the mcp-oauth-callback-url body must be JSON naming a non-empty session id, server name, and callback URL" } : { session, run: async () => await deps.mcpOAuthCallbackUrl(session, serverName, callbackUrl) };
67007
67014
  }
67015
+ },
67016
+ {
67017
+ name: "teleport",
67018
+ path: "teleport",
67019
+ read: (body) => {
67020
+ const session = bodyString(body, "session");
67021
+ const marker = bodyString(body, "marker");
67022
+ return session === void 0 || marker === void 0 ? { error: "the teleport body must be JSON naming a non-empty session id and marker" } : { session, run: async () => await deps.teleport(session, marker) };
67023
+ }
67008
67024
  }
67009
67025
  ];
67010
67026
  return (request7, response) => {
@@ -67368,7 +67384,8 @@ function frontDoorRcControl(transport, token) {
67368
67384
  mcpStatus: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-status`, JSON.stringify({ session: sessionId }), (status, message) => `requesting the MCP status of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
67369
67385
  mcpReconnect: async (sessionId, serverName) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-reconnect`, JSON.stringify({ session: sessionId, serverName }), (status, message) => `reconnecting MCP server ${serverName} on ${sessionId} failed (HTTP ${String(status)}): ${message}`),
67370
67386
  mcpAuthenticate: async (sessionId, serverName, redirectUri) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-authenticate`, JSON.stringify({ session: sessionId, serverName, redirectUri }), (status, message) => `authenticating MCP server ${serverName} on ${sessionId} failed (HTTP ${String(status)}): ${message}`),
67371
- mcpOAuthCallbackUrl: async (sessionId, serverName, callbackUrl) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-oauth-callback-url`, JSON.stringify({ session: sessionId, serverName, callbackUrl }), (status, message) => `handing MCP server ${serverName}'s OAuth callback to ${sessionId} failed (HTTP ${String(status)}): ${message}`)
67387
+ mcpOAuthCallbackUrl: async (sessionId, serverName, callbackUrl) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-oauth-callback-url`, JSON.stringify({ session: sessionId, serverName, callbackUrl }), (status, message) => `handing MCP server ${serverName}'s OAuth callback to ${sessionId} failed (HTTP ${String(status)}): ${message}`),
67388
+ teleport: async (sessionId, marker) => await writeOf(`${CONTROL_PATH_PREFIX}/teleport`, JSON.stringify({ session: sessionId, marker }), (status, message) => `teleporting a marker into ${sessionId} failed (HTTP ${String(status)}): ${message}`)
67372
67389
  };
67373
67390
  }
67374
67391
 
@@ -67650,36 +67667,38 @@ function tlsFacts(options) {
67650
67667
  }
67651
67668
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
67652
67669
  const agent = new ExemptTlsAgent();
67653
- return {
67654
- writeEvents: async (sessionId, headers, body) => await new Promise((resolve, reject) => {
67655
- const options = {
67656
- host: target.host,
67657
- port: target.port,
67658
- method: "POST",
67659
- path: `/v1/code/sessions/${encodeURIComponent(sessionId)}/events`,
67660
- // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
67661
- headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
67662
- agent
67663
- };
67664
- options.servername = target.servername ?? target.host;
67665
- if (target.ca !== void 0) {
67666
- options.ca = [...target.ca];
67667
- }
67668
- if (target.rejectUnauthorized !== void 0) {
67669
- options.rejectUnauthorized = target.rejectUnauthorized;
67670
- }
67671
- const request7 = https3.request(options, (response) => {
67672
- const chunks = [];
67673
- response.on("data", (chunk) => {
67674
- chunks.push(chunk);
67675
- });
67676
- response.on("end", () => {
67677
- resolve({ status: response.statusCode ?? HTTP_BAD_GATEWAY, body: Buffer.concat(chunks).toString("utf8") });
67678
- });
67670
+ const post = async (path46, headers, body) => await new Promise((resolve, reject) => {
67671
+ const options = {
67672
+ host: target.host,
67673
+ port: target.port,
67674
+ method: "POST",
67675
+ path: path46,
67676
+ // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
67677
+ headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
67678
+ agent
67679
+ };
67680
+ options.servername = target.servername ?? target.host;
67681
+ if (target.ca !== void 0) {
67682
+ options.ca = [...target.ca];
67683
+ }
67684
+ if (target.rejectUnauthorized !== void 0) {
67685
+ options.rejectUnauthorized = target.rejectUnauthorized;
67686
+ }
67687
+ const request7 = https3.request(options, (response) => {
67688
+ const chunks = [];
67689
+ response.on("data", (chunk) => {
67690
+ chunks.push(chunk);
67679
67691
  });
67680
- request7.once("error", reject);
67681
- request7.end(body);
67682
- })
67692
+ response.on("end", () => {
67693
+ resolve({ status: response.statusCode ?? HTTP_BAD_GATEWAY, body: Buffer.concat(chunks).toString("utf8") });
67694
+ });
67695
+ });
67696
+ request7.once("error", reject);
67697
+ request7.end(body);
67698
+ });
67699
+ return {
67700
+ writeEvents: async (sessionId, headers, body) => await post(`/v1/code/sessions/${encodeURIComponent(sessionId)}/events`, headers, body),
67701
+ writeTeleportEvents: async (sessionId, headers, body) => await post(`/v1/code/sessions/${encodeURIComponent(sessionId)}/teleport-events`, headers, body)
67683
67702
  };
67684
67703
  }
67685
67704
  var NO_CHUNKS = {
@@ -67697,7 +67716,8 @@ function lateRcEventDial(resolve) {
67697
67716
  return built.dial;
67698
67717
  };
67699
67718
  return {
67700
- writeEvents: async (sessionId, headers, body) => await dialFor().writeEvents(sessionId, headers, body)
67719
+ writeEvents: async (sessionId, headers, body) => await dialFor().writeEvents(sessionId, headers, body),
67720
+ writeTeleportEvents: async (sessionId, headers, body) => await dialFor().writeTeleportEvents(sessionId, headers, body)
67701
67721
  };
67702
67722
  }
67703
67723
  function lateRcStreamDial(resolve) {
@@ -67710,7 +67730,8 @@ function lateRcStreamDial(resolve) {
67710
67730
  return built.dial;
67711
67731
  };
67712
67732
  return {
67713
- announcePresence: async (sessionId, headers, clientId) => await dialFor().announcePresence(sessionId, headers, clientId),
67733
+ announcePresence: async (sessionId, headers, clientId, clear) => await dialFor().announcePresence(sessionId, headers, clientId, clear),
67734
+ markRead: async (sessionId, headers, eventId) => await dialFor().markRead(sessionId, headers, eventId),
67714
67735
  openStream: async (sessionId, headers, resume, signal) => await dialFor().openStream(sessionId, headers, resume, signal)
67715
67736
  };
67716
67737
  }
@@ -67752,11 +67773,16 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
67752
67773
  return Buffer.concat(chunks).toString("utf8");
67753
67774
  };
67754
67775
  return {
67755
- announcePresence: async (sessionId, headers, clientId) => {
67756
- const body = JSON.stringify({ client_id: clientId, clear: false });
67776
+ announcePresence: async (sessionId, headers, clientId, clear) => {
67777
+ const body = JSON.stringify({ client_id: clientId, clear });
67757
67778
  const { status, response } = await request7("POST", `/v1/code/sessions/${encodeURIComponent(sessionId)}/client/presence`, { ...headers, "content-type": "application/json" }, body, new AbortController().signal);
67758
67779
  return { status, body: await readAll(response) };
67759
67780
  },
67781
+ markRead: async (sessionId, headers, eventId) => {
67782
+ const body = JSON.stringify(buildRcMarkReadBody(eventId));
67783
+ const { status, response } = await request7("POST", `/v1/code/sessions/${encodeURIComponent(sessionId)}/mark_read`, { ...headers, "content-type": "application/json" }, body, new AbortController().signal);
67784
+ return { status, body: await readAll(response) };
67785
+ },
67760
67786
  openStream: async (sessionId, headers, resume, signal) => {
67761
67787
  const path46 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
67762
67788
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
@@ -69640,6 +69666,166 @@ var CheckReportJsonSchema = external_exports.strictObject({
69640
69666
 
69641
69667
  // src/frontdoor/controlSchemas.ts
69642
69668
  var import_node_path33 = __toESM(require("node:path"), 1);
69669
+
69670
+ // src/frontdoor/rcSchemas.ts
69671
+ var RcPermissionModeSchema = external_exports.enum(RC_PERMISSION_MODES);
69672
+ var RcSessionSummarySchema = external_exports.strictObject({
69673
+ id: external_exports.string(),
69674
+ createdAt: external_exports.number(),
69675
+ lastSeenAt: external_exports.number()
69676
+ });
69677
+ function workerFactSchema(value2) {
69678
+ return external_exports.strictObject({ value: value2, observedAt: external_exports.number() });
69679
+ }
69680
+ var RcPendingRequestSummarySchema = external_exports.strictObject({
69681
+ sessionId: external_exports.string(),
69682
+ requestId: external_exports.string(),
69683
+ type: external_exports.string(),
69684
+ summary: external_exports.string(),
69685
+ observedAt: external_exports.number()
69686
+ });
69687
+ var RcSessionStatusSchema = external_exports.strictObject({
69688
+ ...RcSessionSummarySchema.shape,
69689
+ workerState: workerFactSchema(external_exports.string()).optional(),
69690
+ workerIdleSeconds: workerFactSchema(external_exports.number()).optional(),
69691
+ pending: external_exports.readonly(external_exports.array(RcPendingRequestSummarySchema))
69692
+ });
69693
+ var RcStreamEnvelopeSchema = external_exports.looseObject({
69694
+ /** The envelope's own event id, when the host sent one. */
69695
+ event_id: external_exports.string().optional(),
69696
+ /** The envelope's event type, the discriminator a consumer switches on (`control_request`, `user`, and kin). */
69697
+ event_type: external_exports.string(),
69698
+ /** The sequence number the host assigned, the value a resume continues after. */
69699
+ sequence_num: external_exports.int(),
69700
+ /** Who emitted the event (`worker` for the CLI's half, a client id for a client's). */
69701
+ source: external_exports.string(),
69702
+ /** The event's payload, carried verbatim: its shape is the payload family's, narrowed by whichever consumer needs it. Optional in the schema's own type because the door forwards the host's envelope as it arrived, asserting only the fields it relies on itself. */
69703
+ payload: external_exports.unknown().optional(),
69704
+ /** When the host created the event; the protocol's own type for this field is not established here, so it is forwarded rather than asserted. */
69705
+ created_at: external_exports.unknown().optional()
69706
+ });
69707
+ var RcStreamEventSchema = external_exports.strictObject({
69708
+ session: external_exports.string(),
69709
+ envelope: RcStreamEnvelopeSchema
69710
+ });
69711
+ var RcRateLimitWindowSchema = external_exports.looseObject({
69712
+ /** 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). */
69713
+ utilization: external_exports.number().optional(),
69714
+ /** 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. */
69715
+ resetsAt: external_exports.number().optional()
69716
+ });
69717
+ var RcRateLimitInfoSchema = external_exports.looseObject({
69718
+ /** The limiting window's own status (`allowed`, `allowed_warning`, `rejected`), asserted only as a string because the vocabulary grows with the CLI. */
69719
+ status: external_exports.string(),
69720
+ /** When the limiting window resets, in unix epoch seconds. */
69721
+ resetsAt: external_exports.number().optional(),
69722
+ /** Which window the top-level fields describe (`five_hour`, `seven_day`, and kin), the payload's own name for it. */
69723
+ rateLimitType: external_exports.string().optional(),
69724
+ /** The fraction of the limiting window used, on the same scale the per-window utilizations carry. */
69725
+ utilization: external_exports.number().optional(),
69726
+ /** Whether usage beyond the plan (extra usage) is currently covering the overflow, the payload's own flag for it. */
69727
+ isUsingOverage: external_exports.boolean().optional(),
69728
+ /** The overage's own status, the same vocabulary the limiting window's `status` carries. */
69729
+ overageStatus: external_exports.string().optional(),
69730
+ /** When the overage window resets, in unix epoch seconds. */
69731
+ overageResetsAt: external_exports.number().optional(),
69732
+ /** 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. */
69733
+ unifiedWindows: external_exports.looseObject({ five_hour: RcRateLimitWindowSchema.optional(), seven_day: RcRateLimitWindowSchema.optional(), seven_day_overage_included: RcRateLimitWindowSchema.optional() }).optional()
69734
+ });
69735
+ var RcLiveRateLimitSchema = external_exports.strictObject({
69736
+ session: external_exports.string(),
69737
+ observedAt: external_exports.number(),
69738
+ rateLimit: RcRateLimitInfoSchema
69739
+ });
69740
+ var RcSessionQuerySchema = external_exports.strictObject({
69741
+ session: external_exports.string().min(1).optional()
69742
+ });
69743
+ var RcSendInputSchema = external_exports.strictObject({
69744
+ session: external_exports.string().min(1),
69745
+ text: external_exports.string().min(1)
69746
+ });
69747
+ var RcAnswerInputSchema = external_exports.strictObject({
69748
+ session: external_exports.string().min(1),
69749
+ request: external_exports.string().min(1),
69750
+ approve: external_exports.boolean(),
69751
+ text: external_exports.string().optional()
69752
+ }).refine((input2) => !input2.approve || input2.text === void 0 || input2.text === "", { message: "an approval carries no text (the protocol's allow result has no message field); text is the denial message" });
69753
+ var RcInterruptInputSchema = external_exports.strictObject({
69754
+ session: external_exports.string().min(1)
69755
+ });
69756
+ var RcSetModelInputSchema = external_exports.strictObject({
69757
+ session: external_exports.string().min(1),
69758
+ model: external_exports.string().min(1)
69759
+ });
69760
+ var RcSetPermissionModeInputSchema = external_exports.strictObject({
69761
+ session: external_exports.string().min(1),
69762
+ mode: RcPermissionModeSchema
69763
+ });
69764
+ var RcEndSessionInputSchema = external_exports.strictObject({
69765
+ session: external_exports.string().min(1),
69766
+ reason: external_exports.string().min(1).optional()
69767
+ });
69768
+ var RcGetUsageInputSchema = external_exports.strictObject({
69769
+ session: external_exports.string().min(1),
69770
+ skipBehaviors: external_exports.boolean().optional()
69771
+ });
69772
+ var RcGetContextUsageInputSchema = external_exports.strictObject({
69773
+ session: external_exports.string().min(1),
69774
+ detail: external_exports.enum(RC_CONTEXT_USAGE_DETAILS).optional()
69775
+ });
69776
+ var RcReadFileInputSchema = external_exports.strictObject({
69777
+ session: external_exports.string().min(1),
69778
+ path: external_exports.string().min(1),
69779
+ maxBytes: external_exports.number().int().positive().optional(),
69780
+ encoding: external_exports.enum(RC_READ_FILE_ENCODINGS).optional()
69781
+ });
69782
+ var RcFileSuggestionsInputSchema = external_exports.strictObject({
69783
+ session: external_exports.string().min(1),
69784
+ query: external_exports.string()
69785
+ });
69786
+ var RcKeepAliveInputSchema = external_exports.strictObject({
69787
+ session: external_exports.string().min(1)
69788
+ });
69789
+ var RcMcpStatusInputSchema = external_exports.strictObject({
69790
+ session: external_exports.string().min(1)
69791
+ });
69792
+ var RcMcpReconnectInputSchema = external_exports.strictObject({
69793
+ session: external_exports.string().min(1),
69794
+ serverName: external_exports.string().min(1)
69795
+ });
69796
+ var RcMcpAuthenticateInputSchema = external_exports.strictObject({
69797
+ session: external_exports.string().min(1),
69798
+ serverName: external_exports.string().min(1),
69799
+ redirectUri: external_exports.string().min(1)
69800
+ });
69801
+ var RcMcpOAuthCallbackUrlInputSchema = external_exports.strictObject({
69802
+ session: external_exports.string().min(1),
69803
+ serverName: external_exports.string().min(1),
69804
+ callbackUrl: external_exports.string().min(1)
69805
+ });
69806
+ var RcTeleportInputSchema = external_exports.strictObject({
69807
+ session: external_exports.string().min(1),
69808
+ marker: external_exports.string().min(1)
69809
+ });
69810
+ var RcListOutputSchema = external_exports.strictObject({ sessions: external_exports.readonly(external_exports.array(RcSessionSummarySchema)) });
69811
+ var RcStatusOutputSchema = external_exports.strictObject({ statuses: external_exports.readonly(external_exports.array(RcSessionStatusSchema)) });
69812
+ var RcPendingOutputSchema = external_exports.strictObject({ pending: external_exports.readonly(external_exports.array(RcPendingRequestSummarySchema)) });
69813
+ var RcWriteOutputSchema = external_exports.strictObject({
69814
+ session: external_exports.string(),
69815
+ sequenceNums: external_exports.readonly(external_exports.array(external_exports.number()))
69816
+ });
69817
+ var RcControlWriteOutputSchema = external_exports.strictObject({
69818
+ session: external_exports.string(),
69819
+ request: external_exports.string(),
69820
+ sequenceNums: external_exports.readonly(external_exports.array(external_exports.number()))
69821
+ });
69822
+ var RcAnswerOutputSchema = external_exports.strictObject({
69823
+ session: external_exports.string(),
69824
+ request: external_exports.string(),
69825
+ sequenceNums: external_exports.readonly(external_exports.array(external_exports.number()))
69826
+ });
69827
+
69828
+ // src/frontdoor/controlSchemas.ts
69643
69829
  var UsageListOutputSchema = external_exports.strictObject({ snapshots: external_exports.readonly(external_exports.array(UsageSnapshotSchema)) });
69644
69830
  var UsageWindowsInputSchema = external_exports.strictObject({
69645
69831
  identity: external_exports.string().min(1),
@@ -69663,6 +69849,12 @@ var UsageWindowsOutputSchema = external_exports.strictObject({
69663
69849
  fiveHour: EffectiveWindowSchema.optional(),
69664
69850
  sevenDay: EffectiveWindowSchema.optional()
69665
69851
  });
69852
+ var UsageLiveOutputSchema = external_exports.strictObject({
69853
+ /** 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. */
69854
+ latest: RcLiveRateLimitSchema.optional(),
69855
+ /** One observation per session whose stream has filed a rate_limit_event this door generation. */
69856
+ sessions: external_exports.readonly(external_exports.array(RcLiveRateLimitSchema))
69857
+ });
69666
69858
  var FrontDoorSessionStatusSchema = external_exports.strictObject({
69667
69859
  pid: external_exports.int().positive(),
69668
69860
  startedAt: external_exports.number(),
@@ -71966,133 +72158,6 @@ var RPCHandler = class extends NodeHttpHandler {
71966
72158
 
71967
72159
  // src/frontdoor/rcApi.ts
71968
72160
  var import_undici2 = __toESM(require_undici(), 1);
71969
-
71970
- // src/frontdoor/rcSchemas.ts
71971
- var RcPermissionModeSchema = external_exports.enum(RC_PERMISSION_MODES);
71972
- var RcSessionSummarySchema = external_exports.strictObject({
71973
- id: external_exports.string(),
71974
- createdAt: external_exports.number(),
71975
- lastSeenAt: external_exports.number()
71976
- });
71977
- function workerFactSchema(value2) {
71978
- return external_exports.strictObject({ value: value2, observedAt: external_exports.number() });
71979
- }
71980
- var RcPendingRequestSummarySchema = external_exports.strictObject({
71981
- sessionId: external_exports.string(),
71982
- requestId: external_exports.string(),
71983
- type: external_exports.string(),
71984
- summary: external_exports.string(),
71985
- observedAt: external_exports.number()
71986
- });
71987
- var RcSessionStatusSchema = external_exports.strictObject({
71988
- ...RcSessionSummarySchema.shape,
71989
- workerState: workerFactSchema(external_exports.string()).optional(),
71990
- workerIdleSeconds: workerFactSchema(external_exports.number()).optional(),
71991
- pending: external_exports.readonly(external_exports.array(RcPendingRequestSummarySchema))
71992
- });
71993
- var RcStreamEnvelopeSchema = external_exports.looseObject({
71994
- /** The envelope's own event id, when the host sent one. */
71995
- event_id: external_exports.string().optional(),
71996
- /** The envelope's event type, the discriminator a consumer switches on (`control_request`, `user`, and kin). */
71997
- event_type: external_exports.string(),
71998
- /** The sequence number the host assigned, the value a resume continues after. */
71999
- sequence_num: external_exports.int(),
72000
- /** Who emitted the event (`worker` for the CLI's half, a client id for a client's). */
72001
- source: external_exports.string(),
72002
- /** The event's payload, carried verbatim: its shape is the payload family's, narrowed by whichever consumer needs it. Optional in the schema's own type because the door forwards the host's envelope as it arrived, asserting only the fields it relies on itself. */
72003
- payload: external_exports.unknown().optional(),
72004
- /** When the host created the event; the protocol's own type for this field is not established here, so it is forwarded rather than asserted. */
72005
- created_at: external_exports.unknown().optional()
72006
- });
72007
- var RcStreamEventSchema = external_exports.strictObject({
72008
- session: external_exports.string(),
72009
- envelope: RcStreamEnvelopeSchema
72010
- });
72011
- var RcSessionQuerySchema = external_exports.strictObject({
72012
- session: external_exports.string().min(1).optional()
72013
- });
72014
- var RcSendInputSchema = external_exports.strictObject({
72015
- session: external_exports.string().min(1),
72016
- text: external_exports.string().min(1)
72017
- });
72018
- var RcAnswerInputSchema = external_exports.strictObject({
72019
- session: external_exports.string().min(1),
72020
- request: external_exports.string().min(1),
72021
- approve: external_exports.boolean(),
72022
- text: external_exports.string().optional()
72023
- }).refine((input2) => !input2.approve || input2.text === void 0 || input2.text === "", { message: "an approval carries no text (the protocol's allow result has no message field); text is the denial message" });
72024
- var RcInterruptInputSchema = external_exports.strictObject({
72025
- session: external_exports.string().min(1)
72026
- });
72027
- var RcSetModelInputSchema = external_exports.strictObject({
72028
- session: external_exports.string().min(1),
72029
- model: external_exports.string().min(1)
72030
- });
72031
- var RcSetPermissionModeInputSchema = external_exports.strictObject({
72032
- session: external_exports.string().min(1),
72033
- mode: RcPermissionModeSchema
72034
- });
72035
- var RcEndSessionInputSchema = external_exports.strictObject({
72036
- session: external_exports.string().min(1),
72037
- reason: external_exports.string().min(1).optional()
72038
- });
72039
- var RcGetUsageInputSchema = external_exports.strictObject({
72040
- session: external_exports.string().min(1),
72041
- skipBehaviors: external_exports.boolean().optional()
72042
- });
72043
- var RcGetContextUsageInputSchema = external_exports.strictObject({
72044
- session: external_exports.string().min(1),
72045
- detail: external_exports.enum(RC_CONTEXT_USAGE_DETAILS).optional()
72046
- });
72047
- var RcReadFileInputSchema = external_exports.strictObject({
72048
- session: external_exports.string().min(1),
72049
- path: external_exports.string().min(1),
72050
- maxBytes: external_exports.number().int().positive().optional(),
72051
- encoding: external_exports.enum(RC_READ_FILE_ENCODINGS).optional()
72052
- });
72053
- var RcFileSuggestionsInputSchema = external_exports.strictObject({
72054
- session: external_exports.string().min(1),
72055
- query: external_exports.string()
72056
- });
72057
- var RcKeepAliveInputSchema = external_exports.strictObject({
72058
- session: external_exports.string().min(1)
72059
- });
72060
- var RcMcpStatusInputSchema = external_exports.strictObject({
72061
- session: external_exports.string().min(1)
72062
- });
72063
- var RcMcpReconnectInputSchema = external_exports.strictObject({
72064
- session: external_exports.string().min(1),
72065
- serverName: external_exports.string().min(1)
72066
- });
72067
- var RcMcpAuthenticateInputSchema = external_exports.strictObject({
72068
- session: external_exports.string().min(1),
72069
- serverName: external_exports.string().min(1),
72070
- redirectUri: external_exports.string().min(1)
72071
- });
72072
- var RcMcpOAuthCallbackUrlInputSchema = external_exports.strictObject({
72073
- session: external_exports.string().min(1),
72074
- serverName: external_exports.string().min(1),
72075
- callbackUrl: external_exports.string().min(1)
72076
- });
72077
- var RcListOutputSchema = external_exports.strictObject({ sessions: external_exports.readonly(external_exports.array(RcSessionSummarySchema)) });
72078
- var RcStatusOutputSchema = external_exports.strictObject({ statuses: external_exports.readonly(external_exports.array(RcSessionStatusSchema)) });
72079
- var RcPendingOutputSchema = external_exports.strictObject({ pending: external_exports.readonly(external_exports.array(RcPendingRequestSummarySchema)) });
72080
- var RcWriteOutputSchema = external_exports.strictObject({
72081
- session: external_exports.string(),
72082
- sequenceNums: external_exports.readonly(external_exports.array(external_exports.number()))
72083
- });
72084
- var RcControlWriteOutputSchema = external_exports.strictObject({
72085
- session: external_exports.string(),
72086
- request: external_exports.string(),
72087
- sequenceNums: external_exports.readonly(external_exports.array(external_exports.number()))
72088
- });
72089
- var RcAnswerOutputSchema = external_exports.strictObject({
72090
- session: external_exports.string(),
72091
- request: external_exports.string(),
72092
- sequenceNums: external_exports.readonly(external_exports.array(external_exports.number()))
72093
- });
72094
-
72095
- // src/frontdoor/rcApi.ts
72096
72161
  var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
72097
72162
  var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
72098
72163
  function doorApiAuth(expectedToken) {
@@ -72158,6 +72223,7 @@ function createRcApiRouter(deps) {
72158
72223
  mcpReconnect: authed.input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpReconnect(input2.session, input2.serverName)) })),
72159
72224
  mcpAuthenticate: authed.input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpAuthenticate(input2.session, input2.serverName, input2.redirectUri)) })),
72160
72225
  mcpOAuthCallbackUrl: authed.input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpOAuthCallbackUrl(input2.session, input2.serverName, input2.callbackUrl)) })),
72226
+ teleport: authed.input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.teleport(input2.session, input2.marker)) })),
72161
72227
  subscribe: authed.input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input: input2, signal }) {
72162
72228
  const queue = [];
72163
72229
  let wake;
@@ -72303,6 +72369,16 @@ function createControlApiRouter(deps) {
72303
72369
  ...unified?.fiveHour === void 0 ? {} : { fiveHour: effectiveWindow(unified.fiveHour, now) },
72304
72370
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
72305
72371
  };
72372
+ }),
72373
+ live: authed.input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input: input2 }) => {
72374
+ const sessions = deps.liveRateLimits(input2.session);
72375
+ if (input2.session !== void 0 && sessions.length === 0) {
72376
+ if (deps.list().some((session) => session.id === input2.session)) {
72377
+ throw new ORPCError("NOT_FOUND", { message: `session ${input2.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` });
72378
+ }
72379
+ throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input2.session) });
72380
+ }
72381
+ return { latest: deps.latestRateLimit(), sessions };
72306
72382
  })
72307
72383
  },
72308
72384
  frontdoor: {
@@ -73735,9 +73811,232 @@ function attachingProviderCredential(route, deps) {
73735
73811
  // src/frontdoor/rcCommands.ts
73736
73812
  var import_node_crypto14 = require("node:crypto");
73737
73813
 
73814
+ // src/frontdoor/rcLiveUsage.ts
73815
+ var RC_RATE_LIMIT_EVENT_TYPE = "rate_limit_event";
73816
+ function isRecord4(value2) {
73817
+ return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
73818
+ }
73819
+ function rcRateLimitInfoOf(event) {
73820
+ const payload = event.envelope.payload;
73821
+ if (!isRecord4(payload) || payload.type !== RC_RATE_LIMIT_EVENT_TYPE) {
73822
+ return void 0;
73823
+ }
73824
+ if (!isRecord4(payload.rate_limit_info)) {
73825
+ return void 0;
73826
+ }
73827
+ const parsed = RcRateLimitInfoSchema.safeParse(payload.rate_limit_info);
73828
+ return parsed.success ? parsed.data : void 0;
73829
+ }
73830
+ function createRcLiveUsage(deps) {
73831
+ const observed = /* @__PURE__ */ new Map();
73832
+ deps.hub.subscribe([DOOR_EVENT_SOURCE_RC], (event) => {
73833
+ const stream = RcStreamEventSchema.safeParse(event.payload);
73834
+ if (!stream.success) {
73835
+ return;
73836
+ }
73837
+ const rateLimit = rcRateLimitInfoOf(stream.data);
73838
+ if (rateLimit === void 0) {
73839
+ return;
73840
+ }
73841
+ observed.set(stream.data.session, { session: stream.data.session, observedAt: deps.now(), rateLimit });
73842
+ });
73843
+ const sorted = () => [...observed.values()].sort((left, right) => left.observedAt - right.observedAt || (left.session < right.session ? -1 : 1));
73844
+ return {
73845
+ liveOf: (sessionId) => sorted().filter((entry) => sessionId === void 0 || entry.session === sessionId),
73846
+ latestOf: () => sorted().at(-1)
73847
+ };
73848
+ }
73849
+
73738
73850
  // src/frontdoor/rcSelfHostMint.ts
73739
73851
  var import_node_path34 = __toESM(require("node:path"), 1);
73740
73852
 
73853
+ // src/frontdoor/rcSelfHostEndpoints.ts
73854
+ var RC_SOURCE_WORKER = "worker";
73855
+ var RC_SOURCE_CLIENT = "client";
73856
+ function isRecord5(value2) {
73857
+ return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
73858
+ }
73859
+ function parseJsonObject2(body) {
73860
+ let parsed;
73861
+ try {
73862
+ parsed = JSON.parse(body);
73863
+ } catch {
73864
+ return void 0;
73865
+ }
73866
+ return isRecord5(parsed) ? parsed : void 0;
73867
+ }
73868
+ function nonEmptyString2(record2, field) {
73869
+ const value2 = record2 === void 0 ? void 0 : record2[field];
73870
+ return typeof value2 === "string" && value2 !== "" ? value2 : void 0;
73871
+ }
73872
+ function numberOf(record2, field) {
73873
+ const value2 = record2 === void 0 ? void 0 : record2[field];
73874
+ if (typeof value2 === "number" && Number.isFinite(value2)) {
73875
+ return value2;
73876
+ }
73877
+ if (typeof value2 === "string" && /^[0-9]+$/.test(value2)) {
73878
+ return Number(value2);
73879
+ }
73880
+ return void 0;
73881
+ }
73882
+ function pageOfRcChannel(url2, rows, idOf, rowOf) {
73883
+ const query = new URL(url2, "http://127.0.0.1").searchParams;
73884
+ const anchor2 = query.get("after_event_id") ?? query.get("cursor");
73885
+ const rawLimit = query.get("limit");
73886
+ const limit = rawLimit === null ? void 0 : numberOf({ value: rawLimit }, "value");
73887
+ if (limit !== void 0 && limit < 1) {
73888
+ return { error: "the limit names a whole number of rows of at least one" };
73889
+ }
73890
+ const from = anchor2 === null ? 0 : rows.findIndex((row) => idOf(row) === anchor2) + 1;
73891
+ if (anchor2 !== null && from === 0) {
73892
+ return { error: `the anchor names an event id this surface holds no row for: ${anchor2}` };
73893
+ }
73894
+ const page = limit === void 0 ? rows.slice(from) : rows.slice(from, from + limit);
73895
+ const last = page[page.length - 1];
73896
+ return { data: page.map(rowOf), ...last === void 0 ? {} : { next_cursor: idOf(last) } };
73897
+ }
73898
+ async function serveRcClientChannels(ctx, tail, method, maxBatchEvents) {
73899
+ const { request: request7, response, session } = ctx;
73900
+ if (tail === "client/presence" && method === "POST") {
73901
+ const body = parseJsonObject2(await ctx.readBody(request7.body, CONTROL_BODY_CAP_BYTES));
73902
+ const clientId = nonEmptyString2(body, "client_id");
73903
+ const clear = body?.clear;
73904
+ if (clientId === void 0 || clear !== void 0 && typeof clear !== "boolean") {
73905
+ await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "a presence announcement is JSON naming a non-empty client_id, with clear only as a boolean or absent" } });
73906
+ return true;
73907
+ }
73908
+ if (clear === true) {
73909
+ session.clients.delete(clientId);
73910
+ ctx.log?.(`rc selfhost ${session.id}: client ${clientId} cleared its presence`);
73911
+ } else {
73912
+ session.clients.set(clientId, ctx.now());
73913
+ ctx.log?.(`rc selfhost ${session.id}: client ${clientId} announced its presence${session.clients.size === 1 ? "" : ` (${String(session.clients.size)} clients now announced)`}`);
73914
+ }
73915
+ await ctx.answerJson(response, HTTP_STATUS.ok, { refresh_after_seconds: ctx.presenceRefreshSeconds });
73916
+ return true;
73917
+ }
73918
+ if (tail === "mark_read" && method === "POST") {
73919
+ const body = parseJsonObject2(await ctx.readBody(request7.body, CONTROL_BODY_CAP_BYTES));
73920
+ const eventId = nonEmptyString2(body, "event_id");
73921
+ const clientId = nonEmptyString2(body, "client_id");
73922
+ if (body !== void 0 && "event_id" in body && eventId === void 0 || "client_id" in (body ?? {}) && clientId === void 0) {
73923
+ await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "a read receipt is JSON naming the event_id it read or none for the whole session, and client_id only as a non-empty string or absent" } });
73924
+ return true;
73925
+ }
73926
+ const receipt = ctx.publish(session, clientId ?? RC_SOURCE_CLIENT, { type: "mark_read", ...eventId === void 0 ? {} : { event_id: eventId }, ...clientId === void 0 ? {} : { client_id: clientId } }, true);
73927
+ ctx.log?.(`rc selfhost ${session.id}: ${clientId === void 0 ? "an unnamed client" : `client ${clientId}`} marked ${eventId === void 0 ? "the session read" : `event ${eventId} read`} as sequence ${String(receipt.sequenceNum)}`);
73928
+ await ctx.answerJson(response, HTTP_STATUS.ok, {});
73929
+ return true;
73930
+ }
73931
+ if (tail === "teleport-events" && method === "POST") {
73932
+ const body = parseJsonObject2(await ctx.readBody(request7.body, CONTROL_BODY_CAP_BYTES));
73933
+ const events = body?.events;
73934
+ if (!Array.isArray(events) || events.length === 0 || events.length > maxBatchEvents) {
73935
+ await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: `a teleport write is a non-empty array of at most ${String(maxBatchEvents)} events` } });
73936
+ return true;
73937
+ }
73938
+ const results = [];
73939
+ for (const event of events) {
73940
+ if (!isRecord5(event) || !isRecord5(event.payload)) {
73941
+ 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" } });
73942
+ return true;
73943
+ }
73944
+ const published = ctx.publish(session, RC_SOURCE_CLIENT, event.payload);
73945
+ results.push({ sequence_num: String(published.sequenceNum), duplicate: published.duplicate });
73946
+ }
73947
+ ctx.sweep();
73948
+ ctx.log?.(`rc selfhost ${session.id}: teleport write published ${String(results.length)} marker event(s)`);
73949
+ await ctx.answerJson(response, HTTP_STATUS.ok, { results });
73950
+ return true;
73951
+ }
73952
+ if (tail === "teleport-events" && method === "GET") {
73953
+ const page = pageOfRcChannel(request7.url, session.events, (event) => event.eventId, (event) => ({ event_id: event.eventId, payload: event.payload }));
73954
+ if ("error" in page) {
73955
+ await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: page.error } });
73956
+ return true;
73957
+ }
73958
+ await ctx.answerJson(response, HTTP_STATUS.ok, page);
73959
+ return true;
73960
+ }
73961
+ return false;
73962
+ }
73963
+ var compatSessionRow = (session, now) => ({ id: session.id, title: session.title, created_at: new Date(session.createdAt).toISOString(), updated_at: new Date(now()).toISOString(), session_status: "active" });
73964
+ async function serveRcCompatSessions(ctx, pathname, compatPath) {
73965
+ const { request: request7, response } = ctx;
73966
+ const method = request7.method.toUpperCase();
73967
+ if (pathname === compatPath) {
73968
+ if (method !== "GET") {
73969
+ await ctx.answerJson(response, HTTP_STATUS.methodNotAllowed, { type: "error", error: { type: "api_error", message: "the compatibility session list is a GET" } });
73970
+ return;
73971
+ }
73972
+ const listRefusal = ctx.credentialRefusal(request7.headers);
73973
+ if (listRefusal !== void 0) {
73974
+ await ctx.unauthorized(response, listRefusal);
73975
+ return;
73976
+ }
73977
+ await ctx.answerJson(response, HTTP_STATUS.ok, { data: [...ctx.sessions.values()].map((session2) => compatSessionRow(session2, ctx.now)) });
73978
+ return;
73979
+ }
73980
+ const rest = pathname.slice(`${compatPath}/`.length);
73981
+ const slash = rest.indexOf("/");
73982
+ const address = slash === -1 ? rest : rest.slice(0, slash);
73983
+ const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
73984
+ const refusal = ctx.credentialRefusal(request7.headers);
73985
+ if (refusal !== void 0) {
73986
+ await ctx.unauthorized(response, refusal);
73987
+ return;
73988
+ }
73989
+ const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
73990
+ if (compatTail === "") {
73991
+ if (method === "GET") {
73992
+ if (session === void 0) {
73993
+ await ctx.answerJson(response, HTTP_STATUS.notFound, { type: "error", error: { type: "api_error", message: `Session not found: ${address}` } });
73994
+ return;
73995
+ }
73996
+ await ctx.answerJson(response, HTTP_STATUS.ok, compatSessionRow(session, ctx.now));
73997
+ return;
73998
+ }
73999
+ if (method === "PATCH" || method === "PUT") {
74000
+ if (session === void 0) {
74001
+ await ctx.answerJson(response, HTTP_STATUS.notFound, { type: "error", error: { type: "api_error", message: `Session not found: ${address}` } });
74002
+ return;
74003
+ }
74004
+ const body = parseJsonObject2(await ctx.readBody(request7.body, CONTROL_BODY_CAP_BYTES));
74005
+ const title = nonEmptyString2(body, "title");
74006
+ if (title === void 0) {
74007
+ await ctx.answerJson(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "a compatibility session update is JSON naming a non-empty title" } });
74008
+ return;
74009
+ }
74010
+ session.title = title;
74011
+ session.lastTrafficAt = ctx.now();
74012
+ ctx.log?.(`rc selfhost ${session.id}: retitled through the compatibility family`);
74013
+ await ctx.answerJson(response, HTTP_STATUS.ok, compatSessionRow(session, ctx.now));
74014
+ return;
74015
+ }
74016
+ await ctx.answerJson(response, HTTP_STATUS.methodNotAllowed, { type: "error", error: { type: "api_error", message: "the compatibility session read is a GET and its update a PATCH or PUT" } });
74017
+ return;
74018
+ }
74019
+ if ((compatTail === "archive" || compatTail === "unarchive") && method === "POST") {
74020
+ await ctx.readBody(request7.body, CONTROL_BODY_CAP_BYTES);
74021
+ if (session === void 0) {
74022
+ await ctx.answerJson(response, HTTP_STATUS.notFound, { type: "error", error: { type: "api_error", message: `Session not found: ${address}` } });
74023
+ return;
74024
+ }
74025
+ if (compatTail === "unarchive") {
74026
+ await ctx.answerJson(response, HTTP_STATUS.ok, compatSessionRow(session, ctx.now));
74027
+ return;
74028
+ }
74029
+ for (const sink of [...session.workerStreams, ...session.clientStreams]) {
74030
+ sink.retire();
74031
+ }
74032
+ ctx.sessions.delete(session.id);
74033
+ ctx.log?.(`rc selfhost ${session.id}: archived through the compatibility family`);
74034
+ await ctx.answerJson(response, HTTP_STATUS.ok, {});
74035
+ return;
74036
+ }
74037
+ await ctx.answerJson(response, HTTP_STATUS.notFound, { type: "error", error: { type: "api_error", message: `the compatibility session family serves no path "${compatTail}"` } });
74038
+ }
74039
+
73741
74040
  // src/frontdoor/rcWebFetch.ts
73742
74041
  var dns2 = __toESM(require("node:dns"), 1);
73743
74042
  var http6 = __toESM(require("node:http"), 1);
@@ -74006,21 +74305,19 @@ var RC_PRESENCE_REFRESH_SECONDS = 60;
74006
74305
  var RC_SELF_HOST_MAX_BATCH_EVENTS = 100;
74007
74306
  var RC_SELF_HOST_WORKER_EPOCH = 1;
74008
74307
  var RC_STREAM_EVENT_NAME = "client_event";
74009
- var RC_SOURCE_WORKER = "worker";
74010
- var RC_SOURCE_CLIENT = "client";
74011
74308
  var CONFLICT_REASON_HEADER2 = "x-ccr-conflict-reason";
74012
74309
  var CONFLICT_REASON_EPOCH_STALE = "epoch_stale";
74013
- function isRecord4(value2) {
74310
+ function isRecord6(value2) {
74014
74311
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
74015
74312
  }
74016
74313
  function isWebSearchRefusal(value2) {
74017
74314
  return !Array.isArray(value2);
74018
74315
  }
74019
- function nonEmptyString2(record2, field) {
74316
+ function nonEmptyString3(record2, field) {
74020
74317
  const value2 = record2 === void 0 ? void 0 : record2[field];
74021
74318
  return typeof value2 === "string" && value2 !== "" ? value2 : void 0;
74022
74319
  }
74023
- function numberOf(record2, field) {
74320
+ function numberOf2(record2, field) {
74024
74321
  const value2 = record2 === void 0 ? void 0 : record2[field];
74025
74322
  if (typeof value2 === "number" && Number.isFinite(value2)) {
74026
74323
  return value2;
@@ -74087,14 +74384,14 @@ async function readBody3(request7, capBytes) {
74087
74384
  });
74088
74385
  });
74089
74386
  }
74090
- function parseJsonObject2(body) {
74387
+ function parseJsonObject3(body) {
74091
74388
  let parsed;
74092
74389
  try {
74093
74390
  parsed = JSON.parse(body);
74094
74391
  } catch {
74095
74392
  return void 0;
74096
74393
  }
74097
- return isRecord4(parsed) ? parsed : void 0;
74394
+ return isRecord6(parsed) ? parsed : void 0;
74098
74395
  }
74099
74396
  function mintWorkerJwt(randomToken, issuedAt) {
74100
74397
  const encode3 = (value2) => Buffer.from(JSON.stringify(value2), "utf8").toString("base64url");
@@ -74117,11 +74414,16 @@ function createRcSelfHostSurface(deps) {
74117
74414
  for (const session of sessions.values()) {
74118
74415
  while (session.events[0] !== void 0 && now - session.events[0].storedAt > RC_SELF_HOST_RETENTION_MS) {
74119
74416
  const dropped = session.events.shift();
74120
- const uuid3 = dropped === void 0 ? void 0 : nonEmptyString2(dropped.payload, "uuid");
74417
+ const uuid3 = dropped === void 0 ? void 0 : nonEmptyString3(dropped.payload, "uuid");
74121
74418
  if (uuid3 !== void 0) {
74122
74419
  session.seenPayloadUuids.delete(uuid3);
74123
74420
  }
74124
74421
  }
74422
+ for (const [clientId, lastSeenAt] of session.clients) {
74423
+ if (now - lastSeenAt > RC_SELF_HOST_RETENTION_MS) {
74424
+ session.clients.delete(clientId);
74425
+ }
74426
+ }
74125
74427
  if (session.workerStreams.size === 0 && session.clientStreams.size === 0 && now - session.lastTrafficAt > RC_SELF_HOST_RETENTION_MS) {
74126
74428
  sessions.delete(session.id);
74127
74429
  }
@@ -74160,7 +74462,7 @@ function createRcSelfHostSurface(deps) {
74160
74462
  const frameOf = (event) => {
74161
74463
  const envelope = {
74162
74464
  event_id: event.eventId,
74163
- event_type: nonEmptyString2(event.payload, "type") ?? "event",
74465
+ event_type: nonEmptyString3(event.payload, "type") ?? "event",
74164
74466
  sequence_num: event.sequenceNum,
74165
74467
  source: event.source,
74166
74468
  payload: event.payload,
@@ -74174,7 +74476,7 @@ data: ${JSON.stringify(envelope)}
74174
74476
  };
74175
74477
  const holdStream = async (session, which, wantsReplay, request7, response) => {
74176
74478
  const url2 = new URL(request7.url, "http://127.0.0.1");
74177
- const cursor3 = numberOf({ value: url2.searchParams.get("from_sequence_num") }, "value") ?? numberOf({ value: singleHeader2(request7.headers, "last-event-id") }, "value");
74479
+ const cursor3 = numberOf2({ value: url2.searchParams.get("from_sequence_num") }, "value") ?? numberOf2({ value: singleHeader2(request7.headers, "last-event-id") }, "value");
74178
74480
  const replay = cursor3 === void 0 ? [] : session.events.filter((event) => wantsReplay(event) && event.sequenceNum > cursor3);
74179
74481
  response.start(HTTP_STATUS.ok, { "content-type": "text/event-stream", "cache-control": "no-cache" });
74180
74482
  response.flush();
@@ -74203,8 +74505,8 @@ data: ${JSON.stringify(envelope)}
74203
74505
  sink.retire();
74204
74506
  response.end();
74205
74507
  };
74206
- const publish = (session, source, payload) => {
74207
- const uuid3 = nonEmptyString2(payload, "uuid");
74508
+ const publish = (session, source, payload, toWorker = source === RC_SOURCE_CLIENT) => {
74509
+ const uuid3 = nonEmptyString3(payload, "uuid");
74208
74510
  const duplicate = uuid3 !== void 0 && session.seenPayloadUuids.has(uuid3);
74209
74511
  session.sequenceNum += 1;
74210
74512
  const event = {
@@ -74212,9 +74514,9 @@ data: ${JSON.stringify(envelope)}
74212
74514
  eventId: uuid3 ?? deps.newUuid(),
74213
74515
  source,
74214
74516
  // The one enrichment the real service was observed making on the live rig's stream: the wall-clock instant it took the write. The worker's handler ignores it; the door's own parser forwards it verbatim.
74215
- payload: source === RC_SOURCE_CLIENT ? { ...payload, server_received_wall_ms: deps.now() } : payload,
74517
+ payload: source === RC_SOURCE_WORKER ? payload : { ...payload, server_received_wall_ms: deps.now() },
74216
74518
  createdAt: new Date(deps.now()).toISOString(),
74217
- toWorker: source === RC_SOURCE_CLIENT,
74519
+ toWorker,
74218
74520
  storedAt: deps.now()
74219
74521
  };
74220
74522
  session.events.push(event);
@@ -74262,8 +74564,26 @@ data: ${JSON.stringify(envelope)}
74262
74564
  }
74263
74565
  session.lastTrafficAt = deps.now();
74264
74566
  if (tail === "") {
74567
+ if (method === "PATCH" || method === "PUT") {
74568
+ const refusal = credentialRefusal(request7.headers);
74569
+ if (refusal !== void 0) {
74570
+ await unauthorized(response, refusal);
74571
+ return;
74572
+ }
74573
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74574
+ const title = nonEmptyString3(body, "title");
74575
+ if (title === void 0) {
74576
+ await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "a session update is JSON naming a non-empty title" } });
74577
+ return;
74578
+ }
74579
+ session.title = title;
74580
+ session.lastTrafficAt = deps.now();
74581
+ deps.log?.(`rc selfhost ${session.id}: retitled at its client's request`);
74582
+ await answerJson2(response, HTTP_STATUS.ok, {});
74583
+ return;
74584
+ }
74265
74585
  if (method !== "GET") {
74266
- await answerJson2(response, HTTP_STATUS.methodNotAllowed, { type: "error", error: { type: "api_error", message: "the session read is a GET" } });
74586
+ await answerJson2(response, HTTP_STATUS.methodNotAllowed, { type: "error", error: { type: "api_error", message: "the session read is a GET, and its update a PATCH or PUT" } });
74267
74587
  return;
74268
74588
  }
74269
74589
  await answerJson2(response, HTTP_STATUS.ok, { session: { id: session.id, title: session.title, created_at: new Date(session.createdAt).toISOString(), status: "active" } });
@@ -74308,17 +74628,17 @@ data: ${JSON.stringify(envelope)}
74308
74628
  return;
74309
74629
  }
74310
74630
  if (workerTail === "" && method === "PUT") {
74311
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74312
- const claimedEpoch = numberOf(body, "worker_epoch");
74631
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74632
+ const claimedEpoch = numberOf2(body, "worker_epoch");
74313
74633
  if (claimedEpoch !== void 0 && claimedEpoch !== RC_SELF_HOST_WORKER_EPOCH) {
74314
74634
  await epochStale(response);
74315
74635
  return;
74316
74636
  }
74317
- const status = nonEmptyString2(body, "worker_status");
74637
+ const status = nonEmptyString3(body, "worker_status");
74318
74638
  if (status !== void 0) {
74319
74639
  session.workerStatus = status;
74320
74640
  }
74321
- if (isRecord4(body?.external_metadata)) {
74641
+ if (isRecord6(body?.external_metadata)) {
74322
74642
  session.externalMetadata = body.external_metadata;
74323
74643
  }
74324
74644
  await answerJson2(response, HTTP_STATUS.ok, {});
@@ -74335,8 +74655,8 @@ data: ${JSON.stringify(envelope)}
74335
74655
  return;
74336
74656
  }
74337
74657
  if (workerTail === "events" && method === "POST") {
74338
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74339
- const claimedEpoch = numberOf(body, "worker_epoch");
74658
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74659
+ const claimedEpoch = numberOf2(body, "worker_epoch");
74340
74660
  if (claimedEpoch !== void 0 && claimedEpoch !== RC_SELF_HOST_WORKER_EPOCH) {
74341
74661
  await epochStale(response);
74342
74662
  return;
@@ -74348,7 +74668,7 @@ data: ${JSON.stringify(envelope)}
74348
74668
  }
74349
74669
  const results = [];
74350
74670
  for (const event of events) {
74351
- if (!isRecord4(event) || !isRecord4(event.payload)) {
74671
+ if (!isRecord6(event) || !isRecord6(event.payload)) {
74352
74672
  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" } });
74353
74673
  return;
74354
74674
  }
@@ -74369,8 +74689,8 @@ data: ${JSON.stringify(envelope)}
74369
74689
  return;
74370
74690
  }
74371
74691
  if (workerTail === "internal-events" && method === "POST") {
74372
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74373
- const claimedEpoch = numberOf(body, "worker_epoch");
74692
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74693
+ const claimedEpoch = numberOf2(body, "worker_epoch");
74374
74694
  if (claimedEpoch !== void 0 && claimedEpoch !== RC_SELF_HOST_WORKER_EPOCH) {
74375
74695
  await epochStale(response);
74376
74696
  return;
@@ -74381,19 +74701,26 @@ data: ${JSON.stringify(envelope)}
74381
74701
  return;
74382
74702
  }
74383
74703
  for (const event of events) {
74384
- if (isRecord4(event)) {
74385
- session.internalEvents.push({ cursor: deps.newUuid(), body: event });
74704
+ if (isRecord6(event)) {
74705
+ session.internalEvents.push({ eventId: deps.newUuid(), body: event });
74386
74706
  }
74387
74707
  }
74388
74708
  await answerJson2(response, HTTP_STATUS.ok, {});
74389
74709
  return;
74390
74710
  }
74391
74711
  if (workerTail === "internal-events" && method === "GET") {
74392
- const url2 = new URL(request7.url, "http://127.0.0.1");
74393
- const cursor3 = url2.searchParams.get("cursor");
74394
- const from = cursor3 === null ? 0 : session.internalEvents.findIndex((event) => event.cursor === cursor3) + 1;
74395
- const page = session.internalEvents.slice(from);
74396
- await answerJson2(response, HTTP_STATUS.ok, { data: page.map((event) => event.body), next_cursor: page.length === 0 ? void 0 : page[page.length - 1]?.cursor });
74712
+ const query = new URL(request7.url, "http://127.0.0.1").searchParams;
74713
+ if (query.get("session_agent_id") !== null || query.get("subagents") !== null) {
74714
+ await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "this surface keeps one internal-events channel per session, so an agent-scoped read has no subset to serve" } });
74715
+ return;
74716
+ }
74717
+ const page = pageOfRcChannel(request7.url, session.internalEvents, (event) => event.eventId, (event) => ({ event_id: event.eventId, payload: event.body }));
74718
+ if ("error" in page) {
74719
+ const anchorUnknown = query.get("after_event_id") !== null && page.error.startsWith("the anchor names an event id");
74720
+ await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: anchorUnknown ? "after_event_id_not_found" : "invalid_request_error", message: page.error } });
74721
+ return;
74722
+ }
74723
+ await answerJson2(response, HTTP_STATUS.ok, page);
74397
74724
  return;
74398
74725
  }
74399
74726
  if (workerTail === "diagnostics" && method === "POST") {
@@ -74402,8 +74729,8 @@ data: ${JSON.stringify(envelope)}
74402
74729
  return;
74403
74730
  }
74404
74731
  if (workerTail === "web-fetch" && method === "POST") {
74405
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74406
- const target = nonEmptyString2(body, "url");
74732
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74733
+ const target = nonEmptyString3(body, "url");
74407
74734
  if (target === void 0) {
74408
74735
  await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "a worker web-fetch carries one url" } });
74409
74736
  return;
@@ -74425,8 +74752,8 @@ data: ${JSON.stringify(envelope)}
74425
74752
  return;
74426
74753
  }
74427
74754
  if (workerTail === "web-search" && method === "POST") {
74428
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74429
- const query = nonEmptyString2(body, "query");
74755
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74756
+ const query = nonEmptyString3(body, "query");
74430
74757
  if (query === void 0) {
74431
74758
  await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "a worker web-search carries one query" } });
74432
74759
  return;
@@ -74437,7 +74764,7 @@ data: ${JSON.stringify(envelope)}
74437
74764
  await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: "the domain filters of a worker web-search are string arrays" } });
74438
74765
  return;
74439
74766
  }
74440
- const searchProfile = nonEmptyString2(body, "search_profile");
74767
+ const searchProfile = nonEmptyString3(body, "search_profile");
74441
74768
  const backend = deps.webSearch;
74442
74769
  if (backend === void 0) {
74443
74770
  deps.log?.(`rc selfhost ${session.id}: worker web-search of "${query}" refused: no search backend serves this door`);
@@ -74462,7 +74789,7 @@ data: ${JSON.stringify(envelope)}
74462
74789
  return;
74463
74790
  }
74464
74791
  if (tail === "events" && method === "POST") {
74465
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74792
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74466
74793
  const events = body?.events;
74467
74794
  if (!Array.isArray(events) || events.length === 0 || events.length > RC_SELF_HOST_MAX_BATCH_EVENTS) {
74468
74795
  await answerJson2(response, HTTP_STATUS.badRequest, { type: "error", error: { type: "invalid_request_error", message: `a client event write is a non-empty array of at most ${String(RC_SELF_HOST_MAX_BATCH_EVENTS)} events` } });
@@ -74470,7 +74797,7 @@ data: ${JSON.stringify(envelope)}
74470
74797
  }
74471
74798
  const results = [];
74472
74799
  for (const event of events) {
74473
- if (!isRecord4(event) || !isRecord4(event.payload)) {
74800
+ if (!isRecord6(event) || !isRecord6(event.payload)) {
74474
74801
  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" } });
74475
74802
  return;
74476
74803
  }
@@ -74482,26 +74809,14 @@ data: ${JSON.stringify(envelope)}
74482
74809
  return;
74483
74810
  }
74484
74811
  if (tail === "events" && method === "GET") {
74485
- await answerJson2(response, HTTP_STATUS.ok, { data: session.events.map((event) => ({ event_id: event.eventId, event_type: nonEmptyString2(event.payload, "type") ?? "event", sequence_num: event.sequenceNum, source: event.source, payload: event.payload, created_at: event.createdAt })) });
74812
+ await answerJson2(response, HTTP_STATUS.ok, { data: session.events.map((event) => ({ event_id: event.eventId, event_type: nonEmptyString3(event.payload, "type") ?? "event", sequence_num: event.sequenceNum, source: event.source, payload: event.payload, created_at: event.createdAt })) });
74486
74813
  return;
74487
74814
  }
74488
74815
  if (tail === "events/stream" && method === "GET") {
74489
74816
  await holdStream(session, "clientStreams", () => true, request7, response);
74490
74817
  return;
74491
74818
  }
74492
- if (tail === "client/presence" && method === "POST") {
74493
- await readBody3(request7.body, CONTROL_BODY_CAP_BYTES);
74494
- await answerJson2(response, HTTP_STATUS.ok, { refresh_after_seconds: RC_PRESENCE_REFRESH_SECONDS });
74495
- return;
74496
- }
74497
- if (tail === "mark_read" && method === "POST") {
74498
- await readBody3(request7.body, CONTROL_BODY_CAP_BYTES);
74499
- await answerJson2(response, HTTP_STATUS.ok, {});
74500
- return;
74501
- }
74502
- if (tail === "teleport-events" && method === "POST") {
74503
- await readBody3(request7.body, CONTROL_BODY_CAP_BYTES);
74504
- await answerJson2(response, HTTP_STATUS.ok, {});
74819
+ if (await serveRcClientChannels({ request: request7, response, session, answerJson: answerJson2, readBody: readBody3, publish, sweep, now: deps.now, presenceRefreshSeconds: RC_PRESENCE_REFRESH_SECONDS, ...deps.log === void 0 ? {} : { log: deps.log } }, tail, method, RC_SELF_HOST_MAX_BATCH_EVENTS)) {
74505
74820
  return;
74506
74821
  }
74507
74822
  await answerJson2(response, HTTP_STATUS.notFound, { type: "error", error: { type: "api_error", message: `the self-hosted Remote Control surface serves no path "${tail}"` } });
@@ -74518,17 +74833,8 @@ data: ${JSON.stringify(envelope)}
74518
74833
  await noCredential(response);
74519
74834
  return;
74520
74835
  }
74521
- if (pathname === RC_COMPAT_SESSIONS_PATH) {
74522
- if (method !== "GET") {
74523
- await answerJson2(response, HTTP_STATUS.methodNotAllowed, { type: "error", error: { type: "api_error", message: "the compatibility session list is a GET" } });
74524
- return;
74525
- }
74526
- const listRefusal = credentialRefusal(request7.headers);
74527
- if (listRefusal !== void 0) {
74528
- await unauthorized(response, listRefusal);
74529
- return;
74530
- }
74531
- await answerJson2(response, HTTP_STATUS.ok, { data: [] });
74836
+ if (pathname === RC_COMPAT_SESSIONS_PATH || pathname.startsWith(`${RC_COMPAT_SESSIONS_PATH}/`)) {
74837
+ await serveRcCompatSessions({ request: request7, response, sessions, answerJson: answerJson2, readBody: readBody3, credentialRefusal, unauthorized, now: deps.now, ...deps.log === void 0 ? {} : { log: deps.log } }, pathname, RC_COMPAT_SESSIONS_PATH);
74532
74838
  return;
74533
74839
  }
74534
74840
  if (pathname !== RC_SESSIONS_PATH_PREFIX2 && !pathname.startsWith(`${RC_SESSIONS_PATH_PREFIX2}/`)) {
@@ -74542,11 +74848,11 @@ data: ${JSON.stringify(envelope)}
74542
74848
  await unauthorized(response, createRefusal);
74543
74849
  return;
74544
74850
  }
74545
- const body = parseJsonObject2(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74851
+ const body = parseJsonObject3(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
74546
74852
  const session = {
74547
74853
  id: `${RC_SESSION_ID_PREFIX2}${deps.newUuid()}`,
74548
74854
  createdAt: deps.now(),
74549
- title: nonEmptyString2(body, "title"),
74855
+ title: nonEmptyString3(body, "title"),
74550
74856
  workerJwts: /* @__PURE__ */ new Set(),
74551
74857
  sequenceNum: 0,
74552
74858
  events: [],
@@ -74554,6 +74860,7 @@ data: ${JSON.stringify(envelope)}
74554
74860
  workerStreams: /* @__PURE__ */ new Set(),
74555
74861
  clientStreams: /* @__PURE__ */ new Set(),
74556
74862
  internalEvents: [],
74863
+ clients: /* @__PURE__ */ new Map(),
74557
74864
  workerStatus: void 0,
74558
74865
  externalMetadata: void 0,
74559
74866
  lastTrafficAt: deps.now()
@@ -74598,7 +74905,7 @@ data: ${JSON.stringify(envelope)}
74598
74905
  const pathname = new URL(request7.url ?? "/", "http://127.0.0.1").pathname;
74599
74906
  if (host === RC_SELF_HOST_OAUTH_HOST) {
74600
74907
  if (method === "POST" && pathname === "/v1/oauth/token") {
74601
- const body = parseJsonObject2(await readBody3(request7, CONTROL_BODY_CAP_BYTES));
74908
+ const body = parseJsonObject3(await readBody3(request7, CONTROL_BODY_CAP_BYTES));
74602
74909
  const record2 = deps.credentialRecord();
74603
74910
  if (record2 === void 0) {
74604
74911
  answerServerJson(response, HTTP_SERVICE_UNAVAILABLE, { error: "the front door's self-hosted Remote Control surface is on but no credential has been minted for it" });
@@ -74683,7 +74990,7 @@ var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
74683
74990
  var RC_SELF_HOST_RECORD_FILE = "credential.json";
74684
74991
  var SELF_HOST_EMAIL = "selfhost@agent-shim.invalid";
74685
74992
  var SELF_HOST_SUBSCRIPTION_TYPE = "max";
74686
- function isRecord5(value2) {
74993
+ function isRecord7(value2) {
74687
74994
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
74688
74995
  }
74689
74996
  function readJsonObject(fs20, file2) {
@@ -74697,7 +75004,7 @@ function readJsonObject(fs20, file2) {
74697
75004
  } catch {
74698
75005
  return void 0;
74699
75006
  }
74700
- return isRecord5(parsed) ? parsed : void 0;
75007
+ return isRecord7(parsed) ? parsed : void 0;
74701
75008
  }
74702
75009
  function readRcSelfHostRecord(fs20, frontdoorDir) {
74703
75010
  const parsed = readJsonObject(fs20, import_node_path34.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
@@ -74721,7 +75028,7 @@ function mintRcSelfHostCredential(deps) {
74721
75028
  const recordFile = import_node_path34.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
74722
75029
  const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
74723
75030
  const existingCredentials = readJsonObject(deps.fs, credentialsFile);
74724
- const existingOauth = isRecord5(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
75031
+ const existingOauth = isRecord7(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
74725
75032
  const existingToken = typeof existingOauth?.accessToken === "string" && existingOauth.accessToken !== "" ? existingOauth.accessToken : void 0;
74726
75033
  const existingIsOwn = existingToken !== void 0 && previousRecord?.accessToken === existingToken;
74727
75034
  if (existingToken !== void 0 && !existingIsOwn && !deps.force) {
@@ -74738,7 +75045,7 @@ function mintRcSelfHostCredential(deps) {
74738
75045
  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)}
74739
75046
  `);
74740
75047
  const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
74741
- const existingBlock = (value2) => isRecord5(value2) ? value2 : {};
75048
+ const existingBlock = (value2) => isRecord7(value2) ? value2 : {};
74742
75049
  deps.fs.writeFilePrivate(claudeJsonFile, `${JSON.stringify({
74743
75050
  ...claudeJson,
74744
75051
  oauthAccount: {
@@ -74816,9 +75123,54 @@ function formatRcPendingList(pending) {
74816
75123
  function eventExcerpt(text2) {
74817
75124
  return text2.length <= RC_PENDING_SUMMARY_EXCERPT_CHARS ? text2 : `${text2.slice(0, RC_PENDING_SUMMARY_EXCERPT_CHARS)}...`;
74818
75125
  }
75126
+ var PERCENT_SCALE = 100;
75127
+ var MS_PER_SECOND8 = 1e3;
75128
+ function percentOf(fraction) {
75129
+ return `${String(Math.round(fraction * PERCENT_SCALE))}%`;
75130
+ }
75131
+ function resetInstantOf(epochSeconds) {
75132
+ return new Date(epochSeconds * MS_PER_SECOND8).toISOString();
75133
+ }
75134
+ function formatRcRateLimitInfo(info) {
75135
+ const parts = [info.status];
75136
+ if (info.rateLimitType !== void 0) {
75137
+ parts.push(info.rateLimitType);
75138
+ }
75139
+ if (info.utilization !== void 0) {
75140
+ parts.push(percentOf(info.utilization));
75141
+ }
75142
+ if (info.resetsAt !== void 0) {
75143
+ parts.push(`resets ${resetInstantOf(info.resetsAt)}`);
75144
+ }
75145
+ const windows = [];
75146
+ for (const name of ["five_hour", "seven_day", "seven_day_overage_included"]) {
75147
+ const window = info.unifiedWindows?.[name];
75148
+ if (window === void 0) {
75149
+ continue;
75150
+ }
75151
+ const bits = [];
75152
+ if (window.utilization !== void 0) {
75153
+ bits.push(percentOf(window.utilization));
75154
+ }
75155
+ if (window.resetsAt !== void 0) {
75156
+ bits.push(`resets ${resetInstantOf(window.resetsAt)}`);
75157
+ }
75158
+ windows.push(bits.length === 0 ? name : `${name} ${bits.join(" ")}`);
75159
+ }
75160
+ if (windows.length > 0) {
75161
+ parts.push(`windows ${windows.join(", ")}`);
75162
+ }
75163
+ if (info.isUsingOverage === true) {
75164
+ parts.push("overage in use");
75165
+ } else if (info.overageStatus !== void 0) {
75166
+ parts.push(`overage ${info.overageStatus}`);
75167
+ }
75168
+ return parts.join(" ");
75169
+ }
74819
75170
  function formatRcStreamEvent(event) {
74820
75171
  const { envelope } = event;
74821
- const sketch = envelope.payload === void 0 ? "" : ` ${eventExcerpt(JSON.stringify(envelope.payload))}`;
75172
+ const rateLimit = rcRateLimitInfoOf(event);
75173
+ const sketch = rateLimit !== void 0 ? ` ${formatRcRateLimitInfo(rateLimit)}` : envelope.payload === void 0 ? "" : ` ${eventExcerpt(JSON.stringify(envelope.payload))}`;
74822
75174
  return `${event.session} ${envelope.event_type} sequence_num ${String(envelope.sequence_num)} source ${envelope.source}${sketch}`;
74823
75175
  }
74824
75176
  function formatRcSelfHostMint(result) {
@@ -75038,7 +75390,13 @@ function registerRcCommand(frontdoor, paths) {
75038
75390
  ["agent-shim frontdoor rc mcp-oauth-callback-url --session cse_00000000-0000-4000-8000-000000000000 --server github --callback-url https://example.com/oauth/callback?code=x"]
75039
75391
  );
75040
75392
  withExamples(
75041
- rc.command("watch").description("Print the observed sessions' client read stream events as they arrive, the approvals the door's held stream receives above all, until Ctrl-C leaves. Read-only.").argument("[session]", "One cse_ session id, as `frontdoor rc list` shows it; every observed session when omitted.").option("--json", "Print each event as one JSON line as it arrives.").action(async (session, options) => {
75393
+ rc.command("teleport").description("Send one teleport marker into an observed session over the teleport-events channel, the write half the cloud UI's ultrapan path owns on the real service. The marker rides the SDK user-message shape, the line the teleport relay anchors on.").requiredOption("--session <id>", "The cse_ session id, as `frontdoor rc list` shows it.").requiredOption("--marker <text>", "The marker text, the string content the teleport relay anchors on.").option("--json", "Print the delivery result as JSON.").action(async (options) => {
75394
+ reportControlWrite(`teleported a marker into the session`, options.session, await frontDoorRcControlFromState(realFarmFs, paths).teleport(options.session, options.marker), options.json, { marker: options.marker });
75395
+ }),
75396
+ ['agent-shim frontdoor rc teleport --session cse_00000000-0000-4000-8000-000000000000 --marker "__ULTRAPAN_TELEPORT_LOCAL__"']
75397
+ );
75398
+ withExamples(
75399
+ rc.command("watch").description("Print the observed sessions' client read stream events as they arrive, the approvals the door's held stream receives above all, with each rate_limit_event rendered as the account's quota state. Read-only, until Ctrl-C leaves.").argument("[session]", "One cse_ session id, as `frontdoor rc list` shows it; every observed session when omitted.").option("--json", "Print each event as one JSON line as it arrives.").action(async (session, options) => {
75042
75400
  const client = frontDoorRcApiFromState(realFarmFs, paths);
75043
75401
  const leave = new AbortController();
75044
75402
  const onInterrupt = () => {
@@ -75096,11 +75454,11 @@ var import_node_path35 = __toESM(require("node:path"), 1);
75096
75454
  function isSafeSessionId(sessionId) {
75097
75455
  return /^[A-Za-z0-9_-]+$/.test(sessionId);
75098
75456
  }
75099
- function isRecord6(value2) {
75457
+ function isRecord8(value2) {
75100
75458
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
75101
75459
  }
75102
75460
  function credentialOfJson(parsed) {
75103
- if (!isRecord6(parsed)) {
75461
+ if (!isRecord8(parsed)) {
75104
75462
  return void 0;
75105
75463
  }
75106
75464
  const { authorization, anthropicVersion, anthropicClientPlatform } = parsed;
@@ -75130,7 +75488,7 @@ function createRcCredentialStore(fs20, dir) {
75130
75488
  } catch {
75131
75489
  return void 0;
75132
75490
  }
75133
- return isRecord6(parsed) ? parsed : void 0;
75491
+ return isRecord8(parsed) ? parsed : void 0;
75134
75492
  };
75135
75493
  return {
75136
75494
  read: (sessionId) => {
@@ -75244,12 +75602,61 @@ function sketch(value, cap) {
75244
75602
  return text.length > cap ? text.slice(0, cap) + '...' : text;
75245
75603
  }
75246
75604
 
75247
- // The headline text of one Remote Control stream event: the assistant and user payloads that carry a content array of text blocks render as their prose, everything else as its type plus a sketch.
75605
+ // One utilization fraction as a whole percentage, the same rounding the CLI's own watch line applies.
75606
+ function percentOf(fraction) { return String(Math.round(fraction * 100)) + '%'; }
75607
+
75608
+ // The reset instant a rate-limit payload states (unix epoch seconds) as an ISO instant; no countdown is derived from it, because a ticking derivation would claim a freshness the event stream never promised.
75609
+ function resetInstantOf(epochSeconds) { return new Date(epochSeconds * 1000).toISOString(); }
75610
+
75611
+ // Whether one rate-limit payload is readable, narrowed the same way the door's live usage state narrows it: the event type and a rate_limit_info object.
75612
+ function rateLimitInfoOf(payload) {
75613
+ if (payload === undefined || payload === null || typeof payload !== 'object' || payload.type !== 'rate_limit_event') { return undefined; }
75614
+ var info = payload.rate_limit_info;
75615
+ if (info === undefined || info === null || typeof info !== 'object' || typeof info.status !== 'string') { return undefined; }
75616
+ return info;
75617
+ }
75618
+
75619
+ // One rate-limit payload's facts as the quota summary the feed and the header render: the limiting window's status and utilisation, each subscription window, and the overage state, every value the payload's own words.
75620
+ function quotaSummary(info) {
75621
+ var parts = [info.status];
75622
+ if (info.rateLimitType !== undefined) { parts.push(info.rateLimitType); }
75623
+ if (typeof info.utilization === 'number') { parts.push(percentOf(info.utilization)); }
75624
+ if (typeof info.resetsAt === 'number') { parts.push('resets ' + resetInstantOf(info.resetsAt)); }
75625
+ if (info.unifiedWindows !== undefined && info.unifiedWindows !== null && typeof info.unifiedWindows === 'object') {
75626
+ var names = ['five_hour', 'seven_day', 'seven_day_overage_included'];
75627
+ var windows = [];
75628
+ for (var i = 0; i < names.length; i++) {
75629
+ var window = info.unifiedWindows[names[i]];
75630
+ if (window === undefined || window === null) { continue; }
75631
+ var bits = [];
75632
+ if (typeof window.utilization === 'number') { bits.push(percentOf(window.utilization)); }
75633
+ if (typeof window.resetsAt === 'number') { bits.push('resets ' + resetInstantOf(window.resetsAt)); }
75634
+ windows.push(bits.length === 0 ? names[i] : names[i] + ' ' + bits.join(' '));
75635
+ }
75636
+ if (windows.length > 0) { parts.push('windows ' + windows.join(', ')); }
75637
+ }
75638
+ if (info.isUsingOverage === true) { parts.push('overage in use'); }
75639
+ else if (typeof info.overageStatus === 'string') { parts.push('overage ' + info.overageStatus); }
75640
+ return parts.join(' ');
75641
+ }
75642
+
75643
+ // The header's quota text from the door's freshest live observation: the quota summary plus when the door observed it, or the plain statement that none has arrived yet.
75644
+ function quotaText(latest) {
75645
+ if (latest === undefined || latest === null) { return 'quota: not observed yet'; }
75646
+ var info = rateLimitInfoOf({ type: 'rate_limit_event', rate_limit_info: latest.rateLimit });
75647
+ if (info === undefined) { return 'quota: not readable'; }
75648
+ return 'quota: ' + quotaSummary(info) + ' observed ' + new Date(latest.observedAt).toLocaleTimeString();
75649
+ }
75650
+
75651
+ // The headline text of one Remote Control stream event: a rate-limit payload renders as its quota summary, the assistant and user payloads that carry a content array of text blocks render as their prose, everything else as its type plus a sketch.
75248
75652
  function rcLine(event) {
75249
75653
  var envelope = event.envelope;
75250
75654
  var payload = envelope.payload;
75251
75655
  var headline = '';
75252
- if (payload !== undefined && payload !== null && typeof payload === 'object' && Array.isArray(payload.content)) {
75656
+ var rateLimit = rateLimitInfoOf(payload);
75657
+ if (rateLimit !== undefined) {
75658
+ headline = quotaSummary(rateLimit);
75659
+ } else if (payload !== undefined && payload !== null && typeof payload === 'object' && Array.isArray(payload.content)) {
75253
75660
  var parts = [];
75254
75661
  for (var i = 0; i < payload.content.length; i++) {
75255
75662
  var block = payload.content[i];
@@ -75378,6 +75785,13 @@ function refreshPending() {
75378
75785
  rpc('rc/pending', ui !== null && ui.selected !== null ? { session: ui.selected } : {}).then(function (result) { renderPending(result.pending); }, authOrReport('rc/pending'));
75379
75786
  }
75380
75787
 
75788
+ // The header's quota span, fed by the door's live read on the same refresh cycle as the session and pending lists: the freshest rate-limit observation any session's stream has filed, with its observation time so its freshness reads at a glance.
75789
+ function refreshQuota() {
75790
+ rpc('usage/live', {}).then(function (result) {
75791
+ if (ui !== null) { ui.quotaState.textContent = quotaText(result.latest); }
75792
+ }, authOrReport('usage/live'));
75793
+ }
75794
+
75381
75795
  // The one error path every call shares: a 401 means this token is not this generation's, so the page says so and asks for it again; anything else is reported in the feed.
75382
75796
  function authOrReport(what) {
75383
75797
  return function (error) {
@@ -75465,11 +75879,12 @@ function startPage(heldToken) {
75465
75879
  promptTarget: document.getElementById('prompt-target'),
75466
75880
  send: document.getElementById('send'),
75467
75881
  streamState: document.getElementById('stream-state'),
75882
+ quotaState: document.getElementById('quota-state'),
75468
75883
  selected: null,
75469
75884
  };
75470
75885
  document.getElementById('token-form').classList.add('hidden');
75471
75886
  ui.main.classList.remove('hidden');
75472
- document.getElementById('refresh').addEventListener('click', function () { refreshSessions(); refreshPending(); });
75887
+ document.getElementById('refresh').addEventListener('click', function () { refreshSessions(); refreshPending(); refreshQuota(); });
75473
75888
  document.getElementById('send').addEventListener('click', sendPrompt);
75474
75889
  document.getElementById('source-filter').addEventListener('change', function () { runFeed(); });
75475
75890
  ui.prompt.addEventListener('keydown', function (event) {
@@ -75477,7 +75892,8 @@ function startPage(heldToken) {
75477
75892
  });
75478
75893
  refreshSessions();
75479
75894
  refreshPending();
75480
- window.setInterval(function () { refreshSessions(); refreshPending(); }, 4000);
75895
+ refreshQuota();
75896
+ window.setInterval(function () { refreshSessions(); refreshPending(); refreshQuota(); }, 4000);
75481
75897
  runFeed();
75482
75898
  document.getElementById('door-state').textContent = 'connected';
75483
75899
  }
@@ -75556,6 +75972,7 @@ var RC_CLIENT_PAGE_HTML = `<!doctype html>
75556
75972
  <h1>agent-shim Remote Control</h1>
75557
75973
  <span class="state" id="door-state">connecting</span>
75558
75974
  <span class="state" id="stream-state"></span>
75975
+ <span class="state" id="quota-state">quota: not observed yet</span>
75559
75976
  </header>
75560
75977
  <div id="token-form">
75561
75978
  <h2>This door's control token</h2>
@@ -75694,7 +76111,7 @@ function createSseParser() {
75694
76111
  }
75695
76112
  };
75696
76113
  }
75697
- function isRecord7(value2) {
76114
+ function isRecord9(value2) {
75698
76115
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
75699
76116
  }
75700
76117
  function sequenceNumOf(value2) {
@@ -75716,7 +76133,7 @@ function parseRcStreamEnvelope(parsed) {
75716
76133
  } catch {
75717
76134
  return void 0;
75718
76135
  }
75719
- if (!isRecord7(data)) {
76136
+ if (!isRecord9(data)) {
75720
76137
  return void 0;
75721
76138
  }
75722
76139
  const eventType = data.event_type;
@@ -75799,9 +76216,26 @@ function createRcStreamHub(deps) {
75799
76216
  }
75800
76217
  return headers;
75801
76218
  };
76219
+ let receiptFailureLogged = false;
76220
+ const sendReceipt = (attachment, headers, eventId) => {
76221
+ if (eventId === void 0) {
76222
+ return;
76223
+ }
76224
+ deps.dial.markRead(attachment.sessionId, headers, eventId).then(
76225
+ () => {
76226
+ receiptFailureLogged = false;
76227
+ },
76228
+ (error62) => {
76229
+ if (!receiptFailureLogged) {
76230
+ receiptFailureLogged = true;
76231
+ deps.log?.(`rc stream ${attachment.sessionId}: the read receipt for event ${eventId} could not be sent (${error62 instanceof Error ? error62.message : String(error62)}); further receipt failures stay quiet until one lands`);
76232
+ }
76233
+ }
76234
+ );
76235
+ };
75802
76236
  const attempt = async (attachment, credential) => {
75803
76237
  const headers = streamHeaders(credential);
75804
- const presence = await deps.dial.announcePresence(attachment.sessionId, headers, attachment.clientId);
76238
+ const presence = await deps.dial.announcePresence(attachment.sessionId, headers, attachment.clientId, false);
75805
76239
  if (presence.status === HTTP_STATUS.unauthorized) {
75806
76240
  return "unauthorized";
75807
76241
  }
@@ -75821,6 +76255,7 @@ function createRcStreamHub(deps) {
75821
76255
  const parser = createSseParser();
75822
76256
  for await (const chunk of answer.chunks) {
75823
76257
  attachment.controller.signal.throwIfAborted();
76258
+ let lastEventId;
75824
76259
  for (const parsed of parser.write(Buffer.from(chunk).toString("utf8"))) {
75825
76260
  const envelope = parseRcStreamEnvelope(parsed);
75826
76261
  if (envelope === void 0) {
@@ -75828,10 +76263,21 @@ function createRcStreamHub(deps) {
75828
76263
  }
75829
76264
  deps.fileStreamEvent(attachment.sessionId, envelope);
75830
76265
  deps.fanout.publish({ session: attachment.sessionId, envelope });
76266
+ if (typeof envelope.event_id === "string" && envelope.event_type !== "mark_read") {
76267
+ lastEventId = envelope.event_id;
76268
+ }
75831
76269
  }
76270
+ sendReceipt(attachment, headers, lastEventId);
75832
76271
  }
75833
76272
  return "dropped";
75834
76273
  };
76274
+ const clearPresence = (attachment, headers) => {
76275
+ if (headers === void 0) {
76276
+ return;
76277
+ }
76278
+ void deps.dial.announcePresence(attachment.sessionId, headers, attachment.clientId, true).catch(() => {
76279
+ });
76280
+ };
75835
76281
  const runLoop = async (attachment) => {
75836
76282
  let retriedUnauthorized = false;
75837
76283
  for (; ; ) {
@@ -75843,6 +76289,7 @@ function createRcStreamHub(deps) {
75843
76289
  if (!live || credential?.authorization === void 0) {
75844
76290
  deps.log?.(`rc stream ${attachment.sessionId}: the attachment ended (${live ? "the session's client credential is no longer known" : "the tracker gave up on the session"})`);
75845
76291
  persistCursor(attachment.sessionId);
76292
+ clearPresence(attachment, credential === void 0 ? void 0 : streamHeaders(credential));
75846
76293
  if (attachments.get(attachment.sessionId) === attachment) {
75847
76294
  attachments.delete(attachment.sessionId);
75848
76295
  }
@@ -75905,6 +76352,8 @@ function createRcStreamHub(deps) {
75905
76352
  close: () => {
75906
76353
  for (const attachment of attachments.values()) {
75907
76354
  persistCursor(attachment.sessionId);
76355
+ const credential = deps.credentialOf(attachment.sessionId);
76356
+ clearPresence(attachment, credential?.authorization === void 0 ? void 0 : streamHeaders(credential));
75908
76357
  attachment.stop();
75909
76358
  }
75910
76359
  attachments.clear();
@@ -75972,7 +76421,7 @@ var ProviderQuotaError = class extends Error {
75972
76421
  this.name = "ProviderQuotaError";
75973
76422
  }
75974
76423
  };
75975
- var MS_PER_SECOND8 = 1e3;
76424
+ var MS_PER_SECOND9 = 1e3;
75976
76425
  var SECONDS_PER_HOUR = 3600;
75977
76426
  var HOURS_PER_DAY3 = 24;
75978
76427
  var DAYS_PER_MONTH = 30;
@@ -75984,8 +76433,8 @@ var ZAI_QUOTA_URL = `https://${ZAI_HOST}/api/monitor/usage/quota/limit`;
75984
76433
  var ZAI_UNIT_HOURS = 3;
75985
76434
  var ZAI_UNIT_MONTHS = 5;
75986
76435
  var ZAI_UNIT_MS = /* @__PURE__ */ new Map([
75987
- [ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND8],
75988
- [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND8]
76436
+ [ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND9],
76437
+ [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND9]
75989
76438
  ]);
75990
76439
  var ZAI_MEASURES = { TOKENS_LIMIT: "tokens", TIME_LIMIT: "tool-calls" };
75991
76440
  var ZaiLimitSchema = external_exports.object({
@@ -76049,7 +76498,7 @@ var OPENROUTER_HOST = "openrouter.ai";
76049
76498
  var OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
76050
76499
  var OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
76051
76500
  var HTTP_FORBIDDEN = 403;
76052
- var MS_PER_DAY2 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND8;
76501
+ var MS_PER_DAY2 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND9;
76053
76502
  var OpenRouterKeySchema = external_exports.object({
76054
76503
  data: external_exports.object({
76055
76504
  limit: external_exports.number().nonnegative().nullable(),
@@ -76292,6 +76741,7 @@ function realFrontDoorSupervisorPorts(paths) {
76292
76741
  const rcCredentialStore = createRcCredentialStore(realFarmFs, paths.frontdoorRcCredentialsDir);
76293
76742
  const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS, credentialStore: rcCredentialStore });
76294
76743
  const doorEvents = createDoorEventHub();
76744
+ const rcLiveUsage = createRcLiveUsage({ now: () => Date.now(), hub: doorEvents });
76295
76745
  const rcFanout = rcFanoutOnDoorHub(createRcEventFanout(), doorEvents);
76296
76746
  const rcHub = createRcStreamHub({
76297
76747
  now: () => Date.now(),
@@ -76392,7 +76842,11 @@ function realFrontDoorSupervisorPorts(paths) {
76392
76842
  const rcMcpReconnect = async (sessionId, serverName) => await reconnectRcSessionMcpServer(rcControlRequestDeps, sessionId, serverName);
76393
76843
  const rcMcpAuthenticate = async (sessionId, serverName, redirectUri) => await authenticateRcSessionMcpServer(rcControlRequestDeps, sessionId, serverName, redirectUri);
76394
76844
  const rcMcpOAuthCallbackUrl = async (sessionId, serverName, callbackUrl) => await submitRcSessionMcpOAuthCallbackUrl(rcControlRequestDeps, sessionId, serverName, callbackUrl);
76845
+ const rcTeleport = async (sessionId, marker) => await teleportRcSession(rcControlRequestDeps, sessionId, marker);
76395
76846
  const controlDeps = {
76847
+ list: rcTracker.list,
76848
+ liveRateLimits: rcLiveUsage.liveOf,
76849
+ latestRateLimit: rcLiveUsage.latestOf,
76396
76850
  usageSnapshots: () => listUsageSnapshots(realFarmFs, paths.usageSnapshotsDir),
76397
76851
  usageSnapshotOf: (identity) => readUsageSnapshot(realFarmFs, paths.usageSnapshotsDir, identity),
76398
76852
  now: () => Date.now(),
@@ -76409,11 +76863,10 @@ function realFrontDoorSupervisorPorts(paths) {
76409
76863
  },
76410
76864
  log,
76411
76865
  mintLeaf(authority, LOOPBACK_LEAF_NAMES, /* @__PURE__ */ new Date()),
76412
- createRcControlHandler({ expectedToken: rcControlToken, list: rcTracker.list, statusOf: rcTracker.statusOf, pendingOf: rcTracker.pendingOf, inject: rcInject, answer: rcAnswer, interrupt: rcInterrupt, setModel: rcSetModel, setPermissionMode: rcSetPermissionMode, endSession: rcEndSession, getUsage: rcGetUsage, getContextUsage: rcGetContextUsage, readFile: rcReadFile, fileSuggestions: rcFileSuggestions, keepAlive: rcKeepAlive, mcpStatus: rcMcpStatus, mcpReconnect: rcMcpReconnect, mcpAuthenticate: rcMcpAuthenticate, mcpOAuthCallbackUrl: rcMcpOAuthCallbackUrl }),
76866
+ createRcControlHandler({ expectedToken: rcControlToken, list: rcTracker.list, statusOf: rcTracker.statusOf, pendingOf: rcTracker.pendingOf, inject: rcInject, answer: rcAnswer, interrupt: rcInterrupt, setModel: rcSetModel, setPermissionMode: rcSetPermissionMode, endSession: rcEndSession, getUsage: rcGetUsage, getContextUsage: rcGetContextUsage, readFile: rcReadFile, fileSuggestions: rcFileSuggestions, keepAlive: rcKeepAlive, mcpStatus: rcMcpStatus, mcpReconnect: rcMcpReconnect, mcpAuthenticate: rcMcpAuthenticate, mcpOAuthCallbackUrl: rcMcpOAuthCallbackUrl, teleport: rcTeleport }),
76413
76867
  [
76414
76868
  createDoorApiNodeHandler({
76415
76869
  expectedToken: rcControlToken,
76416
- list: rcTracker.list,
76417
76870
  statusOf: rcTracker.statusOf,
76418
76871
  pendingOf: rcTracker.pendingOf,
76419
76872
  inject: rcInject,
@@ -76431,6 +76884,7 @@ function realFrontDoorSupervisorPorts(paths) {
76431
76884
  mcpReconnect: rcMcpReconnect,
76432
76885
  mcpAuthenticate: rcMcpAuthenticate,
76433
76886
  mcpOAuthCallbackUrl: rcMcpOAuthCallbackUrl,
76887
+ teleport: rcTeleport,
76434
76888
  fanout: rcFanout,
76435
76889
  ...controlDeps,
76436
76890
  events: doorEvents