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/cli.cjs +1667 -50
- package/dist/index.cjs +179 -137
- package/dist/index.mjs +178 -136
- package/dist/types/index.d.ts +12 -10
- package/package.json +2 -1
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
|
|
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
|
|
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
|
|
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) =>
|
|
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) {
|