agent-shim 8.27.1 → 8.29.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/index.cjs CHANGED
@@ -5333,10 +5333,113 @@ function createRcCredentialStore(fs12, dir) {
5333
5333
  // src/frontdoor/rcApi.ts
5334
5334
  var import_client = require("@orpc/client");
5335
5335
  var import_fetch = require("@orpc/client/fetch");
5336
+ var import_openapi = require("@orpc/openapi");
5337
+ var import_node = require("@orpc/openapi/node");
5336
5338
  var import_server2 = require("@orpc/server");
5337
- var import_node = require("@orpc/server/node");
5339
+ var import_node2 = require("@orpc/server/node");
5338
5340
  var import_undici = require("undici");
5339
5341
 
5342
+ // package.json
5343
+ var package_default = {
5344
+ name: "agent-shim",
5345
+ version: "8.29.0",
5346
+ description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
5347
+ license: "MIT",
5348
+ author: "Joseph Mearman <joseph@mearman.co.uk>",
5349
+ repository: {
5350
+ type: "git",
5351
+ url: "git+https://github.com/ExaDev/agent-shim.git"
5352
+ },
5353
+ homepage: "https://github.com/ExaDev/agent-shim#readme",
5354
+ bugs: "https://github.com/ExaDev/agent-shim/issues",
5355
+ keywords: [
5356
+ "claude-code",
5357
+ "claude",
5358
+ "cli"
5359
+ ],
5360
+ packageManager: "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
5361
+ type: "module",
5362
+ engines: {
5363
+ node: "^22.18 || >=24"
5364
+ },
5365
+ bin: {
5366
+ "agent-shim": "dist/cli.cjs",
5367
+ "claude-use": "dist/cli.cjs"
5368
+ },
5369
+ files: [
5370
+ "dist/cli.cjs",
5371
+ "dist/index.mjs",
5372
+ "dist/index.cjs",
5373
+ "dist/types"
5374
+ ],
5375
+ scripts: {
5376
+ prepare: "husky && node scripts/build.mts --bundle-only",
5377
+ typecheck: "turbo run _typecheck",
5378
+ _typecheck: "tsc --noEmit",
5379
+ lint: "turbo run _lint",
5380
+ _lint: "eslint . --cache --cache-location .eslintcache --max-warnings 0",
5381
+ test: "turbo run _test",
5382
+ _test: "vitest run",
5383
+ "test:coverage": "turbo run _test:coverage",
5384
+ "_test:coverage": "vitest run --coverage",
5385
+ knip: "turbo run _knip",
5386
+ _knip: "knip --cache",
5387
+ build: "turbo run _build",
5388
+ _build: "node scripts/build.mts",
5389
+ "build:bundle": "node scripts/build.mts --bundle-only",
5390
+ prepublishOnly: "pnpm build:bundle",
5391
+ schema: "node scripts/gen-schema.mts"
5392
+ },
5393
+ dependencies: {
5394
+ "@clack/prompts": "^1.8.0",
5395
+ "@orpc/client": "1.15.4",
5396
+ "@orpc/openapi": "1.15.4",
5397
+ "@orpc/server": "1.15.4",
5398
+ commander: "^15.0.0",
5399
+ cosmiconfig: "^10.0.1",
5400
+ picomatch: "^4.0.7",
5401
+ undici: "7.29.1",
5402
+ zod: "^4.6.1"
5403
+ },
5404
+ devDependencies: {
5405
+ "@commitlint/cli": "^21.2.2",
5406
+ "@commitlint/config-conventional": "^21.2.2",
5407
+ "@exadev/eslint-config": "2.12.1",
5408
+ "@semantic-release/changelog": "^7.0.0",
5409
+ "@semantic-release/git": "^11.0.1",
5410
+ "@semantic-release/npm": "^13.1.5",
5411
+ "@types/node": "^26.5.1",
5412
+ "@types/picomatch": "^4.0.3",
5413
+ "@vitest/coverage-v8": "^4.1.11",
5414
+ "conventional-changelog-conventionalcommits": "^10.4.0",
5415
+ esbuild: "^0.28.2",
5416
+ eslint: "^10.10.0",
5417
+ globals: "^17.12.0",
5418
+ husky: "^9.1.7",
5419
+ jiti: "^2.7.0",
5420
+ knip: "^6.35.1",
5421
+ "lint-staged": "^17.5.0",
5422
+ rollup: "4.64.0",
5423
+ "rollup-plugin-dts": "6.5.1",
5424
+ "semantic-release": "^25.0.9",
5425
+ turbo: "^2.11.5",
5426
+ typescript: "^6.0.3",
5427
+ "typescript-eslint": "^8.70.0",
5428
+ vitest: "^4.1.11"
5429
+ },
5430
+ main: "dist/index.cjs",
5431
+ module: "dist/index.mjs",
5432
+ types: "dist/types/index.d.ts",
5433
+ exports: {
5434
+ ".": {
5435
+ types: "./dist/types/index.d.ts",
5436
+ import: "./dist/index.mjs",
5437
+ require: "./dist/index.cjs"
5438
+ },
5439
+ "./package.json": "./package.json"
5440
+ }
5441
+ };
5442
+
5340
5443
  // src/frontdoor/rcSchemas.ts
5341
5444
  var import_zod4 = require("zod");
5342
5445
  var RcPermissionModeSchema = import_zod4.z.enum(RC_PERMISSION_MODES);
@@ -5498,18 +5601,23 @@ var RcAnswerOutputSchema = import_zod4.z.strictObject({
5498
5601
 
5499
5602
  // src/frontdoor/rcApi.ts
5500
5603
  var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
5604
+ var RC_OPENAPI_DOC_PATH = "/openapi.json";
5501
5605
  var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
5606
+ function doorApiBearer(headers) {
5607
+ const presented = headers.authorization;
5608
+ const bearerPrefix = "bearer ".length;
5609
+ return typeof presented === "string" && presented.slice(0, bearerPrefix).toLowerCase() === "bearer " ? presented.slice(bearerPrefix) : void 0;
5610
+ }
5502
5611
  function doorApiAuth(expectedToken) {
5503
5612
  return import_server2.os.$context().use(({ context, next }) => {
5504
- const presented = context.headers.authorization;
5505
- const bearerPrefix = "bearer ".length;
5506
- const token = typeof presented === "string" && presented.slice(0, bearerPrefix).toLowerCase() === "bearer " ? presented.slice(bearerPrefix) : void 0;
5613
+ const token = doorApiBearer(context.headers);
5507
5614
  if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
5508
5615
  throw new import_client.ORPCError("UNAUTHORIZED", { message: "the front door's typed API demands this generation's control token as a Bearer credential" });
5509
5616
  }
5510
5617
  return next();
5511
5618
  });
5512
5619
  }
5620
+ var RC_API_TAG = "remote-control";
5513
5621
  function createRcApiRouter(deps) {
5514
5622
  const authed = doorApiAuth(deps.expectedToken);
5515
5623
  const delivered = (sessionId, result) => {
@@ -5529,41 +5637,41 @@ function createRcApiRouter(deps) {
5529
5637
  };
5530
5638
  return {
5531
5639
  rc: {
5532
- list: authed.output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
5533
- status: authed.input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
5640
+ 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() })),
5641
+ 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 }) => {
5534
5642
  const statuses = deps.statusOf(input.session);
5535
5643
  if (input.session !== void 0 && !statuses.some((entry) => entry.id === input.session)) {
5536
5644
  throw new import_client.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
5537
5645
  }
5538
5646
  return { statuses };
5539
5647
  }),
5540
- pending: authed.input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
5648
+ 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 }) => {
5541
5649
  const pending = deps.pendingOf(input.session);
5542
5650
  if (input.session !== void 0 && deps.statusOf(input.session).length === 0) {
5543
5651
  throw new import_client.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
5544
5652
  }
5545
5653
  return { pending };
5546
5654
  }),
5547
- send: authed.input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
5548
- answer: authed.input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
5655
+ 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)) })),
5656
+ 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 }) => {
5549
5657
  const decision = { approve: input.approve, message: input.approve || input.text === void 0 ? void 0 : input.text };
5550
5658
  return { session: input.session, request: input.request, sequenceNums: delivered(input.session, await deps.answer(input.session, input.request, decision)) };
5551
5659
  }),
5552
- interrupt: authed.input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
5553
- setModel: authed.input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
5554
- setPermissionMode: authed.input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
5555
- endSession: authed.input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
5556
- getUsage: authed.input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
5557
- getContextUsage: authed.input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
5558
- readFile: authed.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 } })) })),
5559
- fileSuggestions: authed.input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
5560
- keepAlive: authed.input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
5561
- mcpStatus: authed.input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
5562
- mcpReconnect: authed.input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
5563
- mcpAuthenticate: authed.input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
5564
- mcpOAuthCallbackUrl: authed.input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
5565
- teleport: authed.input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
5566
- subscribe: authed.input(RcSessionQuerySchema).output((0, import_server2.eventIterator)(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
5660
+ 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)) })),
5661
+ 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)) })),
5662
+ 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)) })),
5663
+ 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)) })),
5664
+ 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)) })),
5665
+ 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)) })),
5666
+ 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 } })) })),
5667
+ 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)) })),
5668
+ 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)) })),
5669
+ 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)) })),
5670
+ 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)) })),
5671
+ 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)) })),
5672
+ 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)) })),
5673
+ 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)) })),
5674
+ 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 }) {
5567
5675
  const queue = [];
5568
5676
  let wake;
5569
5677
  const detach = deps.fanout.subscribe(input.session, (event) => {
@@ -5600,15 +5708,44 @@ function createRcApiRouter(deps) {
5600
5708
  }
5601
5709
  };
5602
5710
  }
5603
- function doorApiNodeHandlerOf(router) {
5604
- const handler = new import_node.RPCHandler(router, { plugins: [new import_node.BodyLimitPlugin({ maxBodySize: CONTROL_BODY_CAP_BYTES })] });
5711
+ function doorApiNodeHandlerOf(router, expectedToken) {
5712
+ const plugins = [new import_node2.BodyLimitPlugin({ maxBodySize: CONTROL_BODY_CAP_BYTES })];
5713
+ const rpcHandler = new import_node2.RPCHandler(router, { plugins });
5714
+ const restHandler = new import_node.OpenAPIHandler(router, { plugins });
5715
+ let document;
5716
+ const documentOf = async () => document ??= new import_openapi.OpenAPIGenerator().generate(router, { info: { title: "agent-shim front door API", version: package_default.version } });
5605
5717
  return {
5606
5718
  pathPrefix: RC_ORPC_PATH_PREFIX,
5607
- handle: async (request4, response) => await handler.handle(request4, response, { context: { headers: request4.headers }, prefix: RC_ORPC_PATH_PREFIX })
5719
+ handle: async (request4, response) => {
5720
+ if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
5721
+ const token = doorApiBearer(request4.headers);
5722
+ if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
5723
+ const refusal = new import_client.ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
5724
+ response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
5725
+ response.end(JSON.stringify(refusal.toJSON()));
5726
+ return { matched: true };
5727
+ }
5728
+ try {
5729
+ const doc = await documentOf();
5730
+ response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
5731
+ response.end(JSON.stringify(doc));
5732
+ } catch (error) {
5733
+ const refusal = new import_client.ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error instanceof Error ? error.message : String(error)}` });
5734
+ response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
5735
+ response.end(JSON.stringify(refusal.toJSON()));
5736
+ }
5737
+ return { matched: true };
5738
+ }
5739
+ const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers }, prefix: RC_ORPC_PATH_PREFIX });
5740
+ if (rest.matched) {
5741
+ return rest;
5742
+ }
5743
+ return await rpcHandler.handle(request4, response, { context: { headers: request4.headers }, prefix: RC_ORPC_PATH_PREFIX });
5744
+ }
5608
5745
  };
5609
5746
  }
5610
5747
  function createRcApiNodeHandler(deps) {
5611
- return doorApiNodeHandlerOf(createRcApiRouter(deps));
5748
+ return doorApiNodeHandlerOf(createRcApiRouter(deps), deps.expectedToken);
5612
5749
  }
5613
5750
  function frontDoorApiLink(port, ca, token) {
5614
5751
  const dispatcher = new import_undici.Agent({ connect: { ca } });
@@ -10080,11 +10217,12 @@ var LaunchLifecycleEventSchema = import_zod20.z.strictObject({
10080
10217
  });
10081
10218
 
10082
10219
  // src/frontdoor/eventsApi.ts
10220
+ var EVENTS_API_TAG = "events";
10083
10221
  function createEventsApiRouter(deps) {
10084
10222
  const authed = doorApiAuth(deps.expectedToken);
10085
10223
  return {
10086
10224
  events: {
10087
- subscribe: authed.input(DoorEventSourceQuerySchema).output((0, import_server3.eventIterator)(DoorEventSchema)).handler(async function* ({ input, signal }) {
10225
+ 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 }) {
10088
10226
  if (input.sources !== void 0) {
10089
10227
  const live = deps.events.sources();
10090
10228
  const unknown = input.sources.filter((source) => !live.includes(source));
@@ -10117,12 +10255,16 @@ function createEventsApiRouter(deps) {
10117
10255
  }
10118
10256
 
10119
10257
  // src/frontdoor/controlApi.ts
10258
+ var USAGE_API_TAG = "usage";
10259
+ var FRONTDOOR_API_TAG = "frontdoor";
10260
+ var CHECK_API_TAG = "check";
10261
+ var DOCTOR_API_TAG = "doctor";
10120
10262
  function createControlApiRouter(deps) {
10121
10263
  const authed = doorApiAuth(deps.expectedToken);
10122
10264
  return {
10123
10265
  usage: {
10124
- list: authed.output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
10125
- effectiveWindow: authed.input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
10266
+ 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() })),
10267
+ 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 }) => {
10126
10268
  const snapshot = deps.usageSnapshotOf(input.identity);
10127
10269
  if (snapshot === void 0) {
10128
10270
  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` });
@@ -10139,7 +10281,7 @@ function createControlApiRouter(deps) {
10139
10281
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
10140
10282
  };
10141
10283
  }),
10142
- live: authed.input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
10284
+ 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 }) => {
10143
10285
  const sessions = deps.liveRateLimits(input.session);
10144
10286
  if (input.session !== void 0 && sessions.length === 0) {
10145
10287
  if (deps.list().some((session) => session.id === input.session)) {
@@ -10151,15 +10293,15 @@ function createControlApiRouter(deps) {
10151
10293
  })
10152
10294
  },
10153
10295
  frontdoor: {
10154
- status: authed.output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
10155
- sessions: authed.output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
10296
+ 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()),
10297
+ 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 }))
10156
10298
  },
10157
10299
  check: {
10158
10300
  // 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.
10159
- run: authed.input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
10301
+ 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)))
10160
10302
  },
10161
10303
  doctor: {
10162
- run: authed.output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
10304
+ run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
10163
10305
  }
10164
10306
  };
10165
10307
  }
@@ -10167,7 +10309,7 @@ function createDoorApiRouter(deps) {
10167
10309
  return { ...createRcApiRouter(deps), ...createControlApiRouter(deps), ...createEventsApiRouter(deps) };
10168
10310
  }
10169
10311
  function createDoorApiNodeHandler(deps) {
10170
- return doorApiNodeHandlerOf(createDoorApiRouter(deps));
10312
+ return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
10171
10313
  }
10172
10314
  function frontDoorApiClient(port, ca, token) {
10173
10315
  return (0, import_client3.createORPCClient)(frontDoorApiLink(port, ca, token));
@@ -12253,106 +12395,6 @@ function removeDirectoryRule(paths, rulePath) {
12253
12395
  var import_node_crypto10 = require("node:crypto");
12254
12396
  var import_node_path30 = __toESM(require("node:path"), 1);
12255
12397
 
12256
- // package.json
12257
- var package_default = {
12258
- name: "agent-shim",
12259
- version: "8.27.1",
12260
- 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.",
12261
- license: "MIT",
12262
- author: "Joseph Mearman <joseph@mearman.co.uk>",
12263
- repository: {
12264
- type: "git",
12265
- url: "git+https://github.com/ExaDev/agent-shim.git"
12266
- },
12267
- homepage: "https://github.com/ExaDev/agent-shim#readme",
12268
- bugs: "https://github.com/ExaDev/agent-shim/issues",
12269
- keywords: [
12270
- "claude-code",
12271
- "claude",
12272
- "cli"
12273
- ],
12274
- packageManager: "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
12275
- type: "module",
12276
- engines: {
12277
- node: "^22.18 || >=24"
12278
- },
12279
- bin: {
12280
- "agent-shim": "dist/cli.cjs",
12281
- "claude-use": "dist/cli.cjs"
12282
- },
12283
- files: [
12284
- "dist/cli.cjs",
12285
- "dist/index.mjs",
12286
- "dist/index.cjs",
12287
- "dist/types"
12288
- ],
12289
- scripts: {
12290
- prepare: "husky && node scripts/build.mts --bundle-only",
12291
- typecheck: "turbo run _typecheck",
12292
- _typecheck: "tsc --noEmit",
12293
- lint: "turbo run _lint",
12294
- _lint: "eslint . --cache --cache-location .eslintcache --max-warnings 0",
12295
- test: "turbo run _test",
12296
- _test: "vitest run",
12297
- "test:coverage": "turbo run _test:coverage",
12298
- "_test:coverage": "vitest run --coverage",
12299
- knip: "turbo run _knip",
12300
- _knip: "knip --cache",
12301
- build: "turbo run _build",
12302
- _build: "node scripts/build.mts",
12303
- "build:bundle": "node scripts/build.mts --bundle-only",
12304
- prepublishOnly: "pnpm build:bundle",
12305
- schema: "node scripts/gen-schema.mts"
12306
- },
12307
- dependencies: {
12308
- "@clack/prompts": "^1.8.0",
12309
- "@orpc/client": "1.15.4",
12310
- "@orpc/server": "1.15.4",
12311
- commander: "^15.0.0",
12312
- cosmiconfig: "^10.0.1",
12313
- picomatch: "^4.0.7",
12314
- undici: "7.29.1",
12315
- zod: "^4.6.1"
12316
- },
12317
- devDependencies: {
12318
- "@commitlint/cli": "^21.2.2",
12319
- "@commitlint/config-conventional": "^21.2.2",
12320
- "@exadev/eslint-config": "2.12.1",
12321
- "@semantic-release/changelog": "^7.0.0",
12322
- "@semantic-release/git": "^11.0.1",
12323
- "@semantic-release/npm": "^13.1.5",
12324
- "@types/node": "^26.5.1",
12325
- "@types/picomatch": "^4.0.3",
12326
- "@vitest/coverage-v8": "^4.1.11",
12327
- "conventional-changelog-conventionalcommits": "^10.4.0",
12328
- esbuild: "^0.28.2",
12329
- eslint: "^10.10.0",
12330
- globals: "^17.12.0",
12331
- husky: "^9.1.7",
12332
- jiti: "^2.7.0",
12333
- knip: "^6.35.1",
12334
- "lint-staged": "^17.5.0",
12335
- rollup: "4.64.0",
12336
- "rollup-plugin-dts": "6.5.1",
12337
- "semantic-release": "^25.0.9",
12338
- turbo: "^2.11.5",
12339
- typescript: "^6.0.3",
12340
- "typescript-eslint": "^8.70.0",
12341
- vitest: "^4.1.11"
12342
- },
12343
- main: "dist/index.cjs",
12344
- module: "dist/index.mjs",
12345
- types: "dist/types/index.d.ts",
12346
- exports: {
12347
- ".": {
12348
- types: "./dist/types/index.d.ts",
12349
- import: "./dist/index.mjs",
12350
- require: "./dist/index.cjs"
12351
- },
12352
- "./package.json": "./package.json"
12353
- }
12354
- };
12355
-
12356
12398
  // src/launcher/argv.ts
12357
12399
  var ConflictingIdentityError = class extends UsageError {
12358
12400
  constructor(positional, flag) {