claude-use 9.4.3 → 9.5.1

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/index.cjs CHANGED
@@ -2649,7 +2649,7 @@ var init_package = __esm({
2649
2649
  "package.json"() {
2650
2650
  package_default = {
2651
2651
  name: "claude-use",
2652
- version: "9.4.3",
2652
+ version: "9.5.1",
2653
2653
  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.",
2654
2654
  license: "MIT",
2655
2655
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2700,9 +2700,9 @@ var init_package = __esm({
2700
2700
  dependencies: {
2701
2701
  "@anthropic-ai/claude-agent-sdk": "0.3.292",
2702
2702
  "@clack/prompts": "^1.8.0",
2703
- "@orpc/client": "1.15.4",
2704
- "@orpc/openapi": "1.15.4",
2705
- "@orpc/server": "1.15.4",
2703
+ "@orpc/client": "2.0.0-beta.41",
2704
+ "@orpc/openapi": "2.0.0-beta.41",
2705
+ "@orpc/server": "2.0.0-beta.41",
2706
2706
  commander: "^15.0.0",
2707
2707
  cosmiconfig: "^10.0.1",
2708
2708
  picomatch: "^4.0.7",
@@ -6078,11 +6078,11 @@ function ensureFrontDoor(params) {
6078
6078
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
6079
6079
  if (state?.port !== void 0 && state.connectPort !== void 0) {
6080
6080
  const verdict = ports.verifyListener(state.port);
6081
- if (verdict.ok && (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL && !replaced) {
6081
+ if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
6082
6082
  ports.stopSupervisor(supervisorPid);
6083
6083
  while (ports.isRunning(supervisorPid)) {
6084
6084
  if (ports.now() >= deadline) {
6085
- throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}) is older than this launcher (protocol ${String(FRONT_DOOR_PROTOCOL)}) and did not exit when asked. Daemon log: ${paths.frontdoorLogPath}`);
6085
+ throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit. Daemon log: ${paths.frontdoorLogPath}`);
6086
6086
  }
6087
6087
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6088
6088
  }
@@ -6755,7 +6755,7 @@ function runLaunchUpdateCheck(params) {
6755
6755
  return;
6756
6756
  }
6757
6757
  if (mode === "auto") {
6758
- port.spawnDetached(["update"]);
6758
+ port.spawnDetached(["update", "--restart-door"]);
6759
6759
  }
6760
6760
  if (!childStarted) {
6761
6761
  port.writeErr(updateNotifyLine(currentVersion, latest));
@@ -7256,25 +7256,24 @@ var init_trust = __esm({
7256
7256
  });
7257
7257
 
7258
7258
  // src/frontdoor/realFrontDoorPort.ts
7259
+ function realEnsurePorts(paths, spawnDaemon) {
7260
+ return {
7261
+ fs: realFarmFs,
7262
+ isRunning: realIsProcessRunning,
7263
+ now: () => Date.now(),
7264
+ sleep: realSleepSync,
7265
+ spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7266
+ stopSupervisor: (pid) => {
7267
+ process.kill(pid, "SIGTERM");
7268
+ },
7269
+ // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
7270
+ verifyListener: (port) => probeFrontDoorSync(port, import_node_fs10.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7271
+ };
7272
+ }
7259
7273
  function realFrontDoorPort(paths, spawnDaemon) {
7260
7274
  return {
7261
7275
  ensure: (inheritedExtraCaCerts) => {
7262
- const up = ensureFrontDoor({
7263
- paths,
7264
- launcherPid: process.pid,
7265
- ports: {
7266
- fs: realFarmFs,
7267
- isRunning: realIsProcessRunning,
7268
- now: () => Date.now(),
7269
- sleep: realSleepSync,
7270
- spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7271
- stopSupervisor: (pid) => {
7272
- process.kill(pid, "SIGTERM");
7273
- },
7274
- // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
7275
- verifyListener: (port) => probeFrontDoorSync(port, import_node_fs10.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7276
- }
7277
- });
7276
+ const up = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
7278
7277
  const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, variable: "NODE_EXTRA_CA_CERTS", inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
7279
7278
  return {
7280
7279
  port: up.port,
@@ -7296,9 +7295,9 @@ var init_realFrontDoorPort = __esm({
7296
7295
  import_node_fs10 = __toESM(require("node:fs"), 1);
7297
7296
  init_realPorts();
7298
7297
  init_ensure2();
7298
+ init_state();
7299
7299
  init_probe();
7300
7300
  init_trust();
7301
- init_state();
7302
7301
  realTrustBundleFs = {
7303
7302
  readFileUtf8: (file) => import_node_fs10.default.readFileSync(file, "utf8"),
7304
7303
  exists: (file) => import_node_fs10.default.existsSync(file),
@@ -10927,41 +10926,41 @@ function createRcApiRouter(deps) {
10927
10926
  };
10928
10927
  return {
10929
10928
  rc: {
10930
- list: authed.route({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] }).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
10931
- status: authed.route({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
10929
+ list: authed.meta((0, import_openapi.openapi)({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] })).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
10930
+ status: authed.meta((0, import_openapi.openapi)({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
10932
10931
  const statuses = deps.statusOf(input.session);
10933
10932
  if (input.session !== void 0 && !statuses.some((entry) => entry.id === input.session)) {
10934
10933
  throw new import_client.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
10935
10934
  }
10936
10935
  return { statuses };
10937
10936
  }),
10938
- pending: authed.route({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
10937
+ pending: authed.meta((0, import_openapi.openapi)({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
10939
10938
  const pending = deps.pendingOf(input.session);
10940
10939
  if (input.session !== void 0 && deps.statusOf(input.session).length === 0) {
10941
10940
  throw new import_client.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
10942
10941
  }
10943
10942
  return { pending };
10944
10943
  }),
10945
- send: authed.route({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] }).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
10946
- answer: authed.route({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] }).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
10944
+ send: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] })).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
10945
+ answer: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] })).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
10947
10946
  const decision = { approve: input.approve, message: input.approve || input.text === void 0 ? void 0 : input.text };
10948
10947
  return { session: input.session, request: input.request, sequenceNums: delivered(input.session, await deps.answer(input.session, input.request, decision)) };
10949
10948
  }),
10950
- interrupt: authed.route({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] }).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
10951
- setModel: authed.route({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] }).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
10952
- setPermissionMode: authed.route({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] }).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
10953
- endSession: authed.route({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] }).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
10954
- getUsage: authed.route({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] }).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
10955
- getContextUsage: authed.route({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] }).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
10956
- readFile: authed.route({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] }).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.readFile(input.session, input.path, { ...input.maxBytes === void 0 ? {} : { maxBytes: input.maxBytes }, ...input.encoding === void 0 ? {} : { encoding: input.encoding } })) })),
10957
- fileSuggestions: authed.route({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] }).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
10958
- keepAlive: authed.route({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] }).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
10959
- mcpStatus: authed.route({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] }).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
10960
- mcpReconnect: authed.route({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] }).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
10961
- mcpAuthenticate: authed.route({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] }).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
10962
- mcpOAuthCallbackUrl: authed.route({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] }).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
10963
- teleport: authed.route({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] }).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
10964
- subscribe: authed.route({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output((0, import_server2.eventIterator)(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
10949
+ interrupt: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] })).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
10950
+ setModel: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] })).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
10951
+ setPermissionMode: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] })).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
10952
+ endSession: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] })).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
10953
+ getUsage: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] })).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
10954
+ getContextUsage: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] })).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
10955
+ readFile: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] })).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.readFile(input.session, input.path, { ...input.maxBytes === void 0 ? {} : { maxBytes: input.maxBytes }, ...input.encoding === void 0 ? {} : { encoding: input.encoding } })) })),
10956
+ fileSuggestions: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] })).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
10957
+ keepAlive: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] })).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
10958
+ mcpStatus: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] })).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
10959
+ mcpReconnect: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] })).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
10960
+ mcpAuthenticate: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] })).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
10961
+ mcpOAuthCallbackUrl: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] })).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
10962
+ teleport: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] })).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
10963
+ subscribe: authed.meta((0, import_openapi.openapi)({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output((0, import_server2.eventIterator)(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
10965
10964
  const queue = [];
10966
10965
  let wake;
10967
10966
  const detach = deps.fanout.subscribe(input.session, (event) => {
@@ -11003,7 +11002,7 @@ function doorApiNodeHandlerOf(router, expectedToken) {
11003
11002
  const rpcHandler = new import_node2.RPCHandler(router, { plugins });
11004
11003
  const restHandler = new import_node.OpenAPIHandler(router, { plugins });
11005
11004
  let document;
11006
- const documentOf = async () => document ??= new import_openapi.OpenAPIGenerator().generate(router, { info: { title: "agent-shim front door API", version: package_default.version } });
11005
+ const documentOf = async () => document ??= new import_openapi.OpenAPIGenerator().generate(router, { base: { info: { title: "agent-shim front door API", version: package_default.version } } });
11007
11006
  return {
11008
11007
  pathPrefix: RC_ORPC_PATH_PREFIX,
11009
11008
  handle: async (request4, response) => {
@@ -11040,10 +11039,12 @@ function createRcApiNodeHandler(deps) {
11040
11039
  function frontDoorApiLink(port, ca, token) {
11041
11040
  const dispatcher = new import_undici.Agent({ connect: { ca } });
11042
11041
  return new import_fetch.RPCLink({
11043
- url: `https://127.0.0.1:${String(port)}${RC_ORPC_PATH_PREFIX}`,
11042
+ origin: `https://127.0.0.1:${String(port)}`,
11043
+ url: RC_ORPC_PATH_PREFIX,
11044
11044
  headers: { authorization: `Bearer ${token}` },
11045
11045
  // undici's own Request and Response types and the global ones are distinct declarations of the same standard shapes (the package's bundled types sit beside @types/node's own), and its fetch refuses the global Request instance outright, so the call is rebuilt from the request's parts and the answer re-wrapped through the global constructors, never cast between the two. The request body is one bounded JSON object (the same protocol cap the handler enforces), so reading it whole costs nothing; it is the answer that streams.
11046
- fetch: async (request4, _init, options) => {
11046
+ fetch: async (url, init, options) => {
11047
+ const request4 = new Request(url, init);
11047
11048
  const body = request4.body === null ? void 0 : Buffer.from(await request4.arrayBuffer());
11048
11049
  const answered = await (0, import_undici.fetch)(request4.url, {
11049
11050
  method: request4.method,
@@ -11066,6 +11067,7 @@ init_realPorts();
11066
11067
 
11067
11068
  // src/frontdoor/controlApi.ts
11068
11069
  var import_client3 = require("@orpc/client");
11070
+ var import_openapi3 = require("@orpc/openapi");
11069
11071
 
11070
11072
  // src/checkReport.ts
11071
11073
  var import_node_os5 = __toESM(require("node:os"), 1);
@@ -12878,6 +12880,7 @@ var DoctorRunOutputSchema = import_zod19.z.strictObject({
12878
12880
 
12879
12881
  // src/frontdoor/eventsApi.ts
12880
12882
  var import_client2 = require("@orpc/client");
12883
+ var import_openapi2 = require("@orpc/openapi");
12881
12884
  var import_server3 = require("@orpc/server");
12882
12885
 
12883
12886
  // src/frontdoor/eventSchemas.ts
@@ -12924,7 +12927,7 @@ function createEventsApiRouter(deps) {
12924
12927
  const authed = doorApiAuth(deps.expectedToken);
12925
12928
  return {
12926
12929
  events: {
12927
- subscribe: authed.route({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] }).input(DoorEventSourceQuerySchema).output((0, import_server3.eventIterator)(DoorEventSchema)).handler(async function* ({ input, signal }) {
12930
+ subscribe: authed.meta((0, import_openapi2.openapi)({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output((0, import_server3.eventIterator)(DoorEventSchema)).handler(async function* ({ input, signal }) {
12928
12931
  if (input.sources !== void 0) {
12929
12932
  const live = deps.events.sources();
12930
12933
  const unknown = input.sources.filter((source) => !live.includes(source));
@@ -12966,8 +12969,8 @@ function createControlApiRouter(deps) {
12966
12969
  const authed = doorApiAuth(deps.expectedToken);
12967
12970
  return {
12968
12971
  usage: {
12969
- list: authed.route({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] }).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
12970
- effectiveWindow: authed.route({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] }).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
12972
+ list: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
12973
+ effectiveWindow: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
12971
12974
  const snapshot = deps.usageSnapshotOf(input.identity);
12972
12975
  if (snapshot === void 0) {
12973
12976
  throw new import_client3.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
@@ -12984,7 +12987,7 @@ function createControlApiRouter(deps) {
12984
12987
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
12985
12988
  };
12986
12989
  }),
12987
- live: authed.route({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] }).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
12990
+ live: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
12988
12991
  const sessions = deps.liveRateLimits(input.session);
12989
12992
  if (input.session !== void 0 && sessions.length === 0) {
12990
12993
  if (deps.list().some((session) => session.id === input.session)) {
@@ -12996,18 +12999,18 @@ function createControlApiRouter(deps) {
12996
12999
  })
12997
13000
  },
12998
13001
  frontdoor: {
12999
- status: authed.route({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
13000
- sessions: authed.route({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
13002
+ status: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
13003
+ sessions: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
13001
13004
  },
13002
13005
  check: {
13003
13006
  // The report's own JSON shape is the contract (the same one `check --json` prints and `checkReportSchema.ts` defines), so the procedure returns exactly that conversion.
13004
- run: authed.route({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] }).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
13007
+ run: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
13005
13008
  },
13006
13009
  doctor: {
13007
- run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
13010
+ run: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
13008
13011
  },
13009
13012
  pool: {
13010
- pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
13013
+ pick: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
13011
13014
  const report = deps.poolPick(input.pool, input.path);
13012
13015
  if (report === void 0) {
13013
13016
  const live = deps.poolNames();
package/dist/index.mjs CHANGED
@@ -2625,7 +2625,7 @@ var init_package = __esm({
2625
2625
  "package.json"() {
2626
2626
  package_default = {
2627
2627
  name: "claude-use",
2628
- version: "9.4.3",
2628
+ version: "9.5.1",
2629
2629
  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.",
2630
2630
  license: "MIT",
2631
2631
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2676,9 +2676,9 @@ var init_package = __esm({
2676
2676
  dependencies: {
2677
2677
  "@anthropic-ai/claude-agent-sdk": "0.3.292",
2678
2678
  "@clack/prompts": "^1.8.0",
2679
- "@orpc/client": "1.15.4",
2680
- "@orpc/openapi": "1.15.4",
2681
- "@orpc/server": "1.15.4",
2679
+ "@orpc/client": "2.0.0-beta.41",
2680
+ "@orpc/openapi": "2.0.0-beta.41",
2681
+ "@orpc/server": "2.0.0-beta.41",
2682
2682
  commander: "^15.0.0",
2683
2683
  cosmiconfig: "^10.0.1",
2684
2684
  picomatch: "^4.0.7",
@@ -6052,11 +6052,11 @@ function ensureFrontDoor(params) {
6052
6052
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
6053
6053
  if (state?.port !== void 0 && state.connectPort !== void 0) {
6054
6054
  const verdict = ports.verifyListener(state.port);
6055
- if (verdict.ok && (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL && !replaced) {
6055
+ if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
6056
6056
  ports.stopSupervisor(supervisorPid);
6057
6057
  while (ports.isRunning(supervisorPid)) {
6058
6058
  if (ports.now() >= deadline) {
6059
- throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}) is older than this launcher (protocol ${String(FRONT_DOOR_PROTOCOL)}) and did not exit when asked. Daemon log: ${paths.frontdoorLogPath}`);
6059
+ throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit. Daemon log: ${paths.frontdoorLogPath}`);
6060
6060
  }
6061
6061
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6062
6062
  }
@@ -6728,7 +6728,7 @@ function runLaunchUpdateCheck(params) {
6728
6728
  return;
6729
6729
  }
6730
6730
  if (mode === "auto") {
6731
- port.spawnDetached(["update"]);
6731
+ port.spawnDetached(["update", "--restart-door"]);
6732
6732
  }
6733
6733
  if (!childStarted) {
6734
6734
  port.writeErr(updateNotifyLine(currentVersion, latest));
@@ -7229,25 +7229,24 @@ var init_trust = __esm({
7229
7229
 
7230
7230
  // src/frontdoor/realFrontDoorPort.ts
7231
7231
  import fs11 from "node:fs";
7232
+ function realEnsurePorts(paths, spawnDaemon) {
7233
+ return {
7234
+ fs: realFarmFs,
7235
+ isRunning: realIsProcessRunning,
7236
+ now: () => Date.now(),
7237
+ sleep: realSleepSync,
7238
+ spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7239
+ stopSupervisor: (pid) => {
7240
+ process.kill(pid, "SIGTERM");
7241
+ },
7242
+ // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
7243
+ verifyListener: (port) => probeFrontDoorSync(port, fs11.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7244
+ };
7245
+ }
7232
7246
  function realFrontDoorPort(paths, spawnDaemon) {
7233
7247
  return {
7234
7248
  ensure: (inheritedExtraCaCerts) => {
7235
- const up = ensureFrontDoor({
7236
- paths,
7237
- launcherPid: process.pid,
7238
- ports: {
7239
- fs: realFarmFs,
7240
- isRunning: realIsProcessRunning,
7241
- now: () => Date.now(),
7242
- sleep: realSleepSync,
7243
- spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7244
- stopSupervisor: (pid) => {
7245
- process.kill(pid, "SIGTERM");
7246
- },
7247
- // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
7248
- verifyListener: (port) => probeFrontDoorSync(port, fs11.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7249
- }
7250
- });
7249
+ const up = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
7251
7250
  const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, variable: "NODE_EXTRA_CA_CERTS", inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
7252
7251
  return {
7253
7252
  port: up.port,
@@ -7268,9 +7267,9 @@ var init_realFrontDoorPort = __esm({
7268
7267
  "use strict";
7269
7268
  init_realPorts();
7270
7269
  init_ensure2();
7270
+ init_state();
7271
7271
  init_probe();
7272
7272
  init_trust();
7273
- init_state();
7274
7273
  realTrustBundleFs = {
7275
7274
  readFileUtf8: (file) => fs11.readFileSync(file, "utf8"),
7276
7275
  exists: (file) => fs11.existsSync(file),
@@ -10398,7 +10397,7 @@ function createRcCredentialStore(fs12, dir) {
10398
10397
  init_package();
10399
10398
  import { createORPCClient, ORPCError } from "@orpc/client";
10400
10399
  import { RPCLink } from "@orpc/client/fetch";
10401
- import { OpenAPIGenerator } from "@orpc/openapi";
10400
+ import { openapi, OpenAPIGenerator } from "@orpc/openapi";
10402
10401
  import { OpenAPIHandler } from "@orpc/openapi/node";
10403
10402
  import { eventIterator, os as os2, withEventMeta } from "@orpc/server";
10404
10403
  import { BodyLimitPlugin, RPCHandler } from "@orpc/server/node";
@@ -10602,41 +10601,41 @@ function createRcApiRouter(deps) {
10602
10601
  };
10603
10602
  return {
10604
10603
  rc: {
10605
- list: authed.route({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] }).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
10606
- status: authed.route({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
10604
+ list: authed.meta(openapi({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] })).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
10605
+ status: authed.meta(openapi({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
10607
10606
  const statuses = deps.statusOf(input.session);
10608
10607
  if (input.session !== void 0 && !statuses.some((entry) => entry.id === input.session)) {
10609
10608
  throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
10610
10609
  }
10611
10610
  return { statuses };
10612
10611
  }),
10613
- pending: authed.route({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
10612
+ pending: authed.meta(openapi({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
10614
10613
  const pending = deps.pendingOf(input.session);
10615
10614
  if (input.session !== void 0 && deps.statusOf(input.session).length === 0) {
10616
10615
  throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
10617
10616
  }
10618
10617
  return { pending };
10619
10618
  }),
10620
- send: authed.route({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] }).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
10621
- answer: authed.route({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] }).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
10619
+ send: authed.meta(openapi({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] })).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
10620
+ answer: authed.meta(openapi({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] })).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
10622
10621
  const decision = { approve: input.approve, message: input.approve || input.text === void 0 ? void 0 : input.text };
10623
10622
  return { session: input.session, request: input.request, sequenceNums: delivered(input.session, await deps.answer(input.session, input.request, decision)) };
10624
10623
  }),
10625
- interrupt: authed.route({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] }).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
10626
- setModel: authed.route({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] }).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
10627
- setPermissionMode: authed.route({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] }).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
10628
- endSession: authed.route({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] }).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
10629
- getUsage: authed.route({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] }).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
10630
- getContextUsage: authed.route({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] }).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
10631
- readFile: authed.route({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] }).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.readFile(input.session, input.path, { ...input.maxBytes === void 0 ? {} : { maxBytes: input.maxBytes }, ...input.encoding === void 0 ? {} : { encoding: input.encoding } })) })),
10632
- fileSuggestions: authed.route({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] }).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
10633
- keepAlive: authed.route({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] }).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
10634
- mcpStatus: authed.route({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] }).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
10635
- mcpReconnect: authed.route({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] }).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
10636
- mcpAuthenticate: authed.route({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] }).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
10637
- mcpOAuthCallbackUrl: authed.route({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] }).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
10638
- teleport: authed.route({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] }).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
10639
- subscribe: authed.route({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
10624
+ interrupt: authed.meta(openapi({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] })).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
10625
+ setModel: authed.meta(openapi({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] })).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
10626
+ setPermissionMode: authed.meta(openapi({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] })).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
10627
+ endSession: authed.meta(openapi({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] })).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
10628
+ getUsage: authed.meta(openapi({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] })).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
10629
+ getContextUsage: authed.meta(openapi({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] })).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
10630
+ readFile: authed.meta(openapi({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] })).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.readFile(input.session, input.path, { ...input.maxBytes === void 0 ? {} : { maxBytes: input.maxBytes }, ...input.encoding === void 0 ? {} : { encoding: input.encoding } })) })),
10631
+ fileSuggestions: authed.meta(openapi({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] })).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
10632
+ keepAlive: authed.meta(openapi({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] })).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
10633
+ mcpStatus: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] })).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
10634
+ mcpReconnect: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] })).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
10635
+ mcpAuthenticate: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] })).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
10636
+ mcpOAuthCallbackUrl: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] })).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
10637
+ teleport: authed.meta(openapi({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] })).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
10638
+ subscribe: authed.meta(openapi({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
10640
10639
  const queue = [];
10641
10640
  let wake;
10642
10641
  const detach = deps.fanout.subscribe(input.session, (event) => {
@@ -10678,7 +10677,7 @@ function doorApiNodeHandlerOf(router, expectedToken) {
10678
10677
  const rpcHandler = new RPCHandler(router, { plugins });
10679
10678
  const restHandler = new OpenAPIHandler(router, { plugins });
10680
10679
  let document;
10681
- const documentOf = async () => document ??= new OpenAPIGenerator().generate(router, { info: { title: "agent-shim front door API", version: package_default.version } });
10680
+ const documentOf = async () => document ??= new OpenAPIGenerator().generate(router, { base: { info: { title: "agent-shim front door API", version: package_default.version } } });
10682
10681
  return {
10683
10682
  pathPrefix: RC_ORPC_PATH_PREFIX,
10684
10683
  handle: async (request4, response) => {
@@ -10715,10 +10714,12 @@ function createRcApiNodeHandler(deps) {
10715
10714
  function frontDoorApiLink(port, ca, token) {
10716
10715
  const dispatcher = new Agent3({ connect: { ca } });
10717
10716
  return new RPCLink({
10718
- url: `https://127.0.0.1:${String(port)}${RC_ORPC_PATH_PREFIX}`,
10717
+ origin: `https://127.0.0.1:${String(port)}`,
10718
+ url: RC_ORPC_PATH_PREFIX,
10719
10719
  headers: { authorization: `Bearer ${token}` },
10720
10720
  // undici's own Request and Response types and the global ones are distinct declarations of the same standard shapes (the package's bundled types sit beside @types/node's own), and its fetch refuses the global Request instance outright, so the call is rebuilt from the request's parts and the answer re-wrapped through the global constructors, never cast between the two. The request body is one bounded JSON object (the same protocol cap the handler enforces), so reading it whole costs nothing; it is the answer that streams.
10721
- fetch: async (request4, _init, options) => {
10721
+ fetch: async (url, init, options) => {
10722
+ const request4 = new Request(url, init);
10722
10723
  const body = request4.body === null ? void 0 : Buffer.from(await request4.arrayBuffer());
10723
10724
  const answered = await undiciFetch(request4.url, {
10724
10725
  method: request4.method,
@@ -10741,6 +10742,7 @@ init_realPorts();
10741
10742
 
10742
10743
  // src/frontdoor/controlApi.ts
10743
10744
  import { createORPCClient as createORPCClient2, ORPCError as ORPCError3 } from "@orpc/client";
10745
+ import { openapi as openapi3 } from "@orpc/openapi";
10744
10746
 
10745
10747
  // src/checkReport.ts
10746
10748
  init_classify();
@@ -12553,6 +12555,7 @@ var DoctorRunOutputSchema = z19.strictObject({
12553
12555
 
12554
12556
  // src/frontdoor/eventsApi.ts
12555
12557
  import { ORPCError as ORPCError2 } from "@orpc/client";
12558
+ import { openapi as openapi2 } from "@orpc/openapi";
12556
12559
  import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
12557
12560
 
12558
12561
  // src/frontdoor/eventSchemas.ts
@@ -12599,7 +12602,7 @@ function createEventsApiRouter(deps) {
12599
12602
  const authed = doorApiAuth(deps.expectedToken);
12600
12603
  return {
12601
12604
  events: {
12602
- subscribe: authed.route({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] }).input(DoorEventSourceQuerySchema).output(eventIterator2(DoorEventSchema)).handler(async function* ({ input, signal }) {
12605
+ subscribe: authed.meta(openapi2({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output(eventIterator2(DoorEventSchema)).handler(async function* ({ input, signal }) {
12603
12606
  if (input.sources !== void 0) {
12604
12607
  const live = deps.events.sources();
12605
12608
  const unknown = input.sources.filter((source) => !live.includes(source));
@@ -12641,8 +12644,8 @@ function createControlApiRouter(deps) {
12641
12644
  const authed = doorApiAuth(deps.expectedToken);
12642
12645
  return {
12643
12646
  usage: {
12644
- list: authed.route({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] }).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
12645
- effectiveWindow: authed.route({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] }).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
12647
+ list: authed.meta(openapi3({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
12648
+ effectiveWindow: authed.meta(openapi3({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
12646
12649
  const snapshot = deps.usageSnapshotOf(input.identity);
12647
12650
  if (snapshot === void 0) {
12648
12651
  throw new ORPCError3("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
@@ -12659,7 +12662,7 @@ function createControlApiRouter(deps) {
12659
12662
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
12660
12663
  };
12661
12664
  }),
12662
- live: authed.route({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] }).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
12665
+ live: authed.meta(openapi3({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
12663
12666
  const sessions = deps.liveRateLimits(input.session);
12664
12667
  if (input.session !== void 0 && sessions.length === 0) {
12665
12668
  if (deps.list().some((session) => session.id === input.session)) {
@@ -12671,18 +12674,18 @@ function createControlApiRouter(deps) {
12671
12674
  })
12672
12675
  },
12673
12676
  frontdoor: {
12674
- status: authed.route({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
12675
- sessions: authed.route({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
12677
+ status: authed.meta(openapi3({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
12678
+ sessions: authed.meta(openapi3({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
12676
12679
  },
12677
12680
  check: {
12678
12681
  // The report's own JSON shape is the contract (the same one `check --json` prints and `checkReportSchema.ts` defines), so the procedure returns exactly that conversion.
12679
- run: authed.route({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] }).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
12682
+ run: authed.meta(openapi3({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
12680
12683
  },
12681
12684
  doctor: {
12682
- run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
12685
+ run: authed.meta(openapi3({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
12683
12686
  },
12684
12687
  pool: {
12685
- pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
12688
+ pick: authed.meta(openapi3({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
12686
12689
  const report = deps.poolPick(input.pool, input.path);
12687
12690
  if (report === void 0) {
12688
12691
  const live = deps.poolNames();