agent-shim 8.5.6 → 8.6.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
@@ -75,6 +75,7 @@ __export(index_exports, {
75
75
  ProviderSchema: () => ProviderSchema,
76
76
  RC_IDLE_EXPIRY_MS: () => RC_IDLE_EXPIRY_MS,
77
77
  RC_PENDING_DEADLINE_MS: () => RC_PENDING_DEADLINE_MS,
78
+ RC_PERMISSION_MODES: () => RC_PERMISSION_MODES,
78
79
  RC_REQUEST_PARSE_CAP_BYTES: () => RC_REQUEST_PARSE_CAP_BYTES,
79
80
  RC_SESSIONS_PATH_PREFIX: () => RC_SESSIONS_PATH_PREFIX,
80
81
  ROUTED_PATH_PREFIX: () => ROUTED_PATH_PREFIX,
@@ -91,6 +92,9 @@ __export(index_exports, {
91
92
  buildLayoutPaths: () => buildLayoutPaths,
92
93
  buildRcControlResponsePayload: () => buildRcControlResponsePayload,
93
94
  buildRcEventWriteBody: () => buildRcEventWriteBody,
95
+ buildRcInterruptPayload: () => buildRcInterruptPayload,
96
+ buildRcSetModelPayload: () => buildRcSetModelPayload,
97
+ buildRcSetPermissionModePayload: () => buildRcSetPermissionModePayload,
94
98
  buildRcUserMessagePayload: () => buildRcUserMessagePayload,
95
99
  carryOver: () => carryOver,
96
100
  checkReportHasWarnings: () => checkReportHasWarnings,
@@ -115,8 +119,10 @@ __export(index_exports, {
115
119
  generateCa: () => generateCa,
116
120
  identityExists: () => identityExists,
117
121
  injectRcUserMessage: () => injectRcUserMessage,
122
+ interruptRcSession: () => interruptRcSession,
118
123
  isIdentityDirectoryName: () => isIdentityDirectoryName,
119
124
  isInterceptedHost: () => isInterceptedHost,
125
+ isRcPermissionMode: () => isRcPermissionMode,
120
126
  listDirectoryRules: () => listDirectoryRules,
121
127
  listIdentities: () => listIdentities,
122
128
  listProfiles: () => listProfiles,
@@ -172,6 +178,8 @@ __export(index_exports, {
172
178
  setProfileEntries: () => setProfileEntries,
173
179
  setProfileLaunchFlags: () => setProfileLaunchFlags,
174
180
  setProfileMetadata: () => setProfileMetadata,
181
+ setRcSessionModel: () => setRcSessionModel,
182
+ setRcSessionPermissionMode: () => setRcSessionPermissionMode,
175
183
  snapshotPath: () => snapshotPath,
176
184
  startConnectServer: () => startConnectServer,
177
185
  topLevelNames: () => topLevelNames,
@@ -4070,6 +4078,19 @@ function buildRcControlResponsePayload(requestId, decision) {
4070
4078
  const result = decision.approve ? { behavior: "allow" } : { behavior: "deny", message: decision.message ?? "" };
4071
4079
  return { type: "control_response", response: { subtype: "success", request_id: requestId, response: result } };
4072
4080
  }
4081
+ var RC_PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"];
4082
+ function isRcPermissionMode(value) {
4083
+ return RC_PERMISSION_MODES.some((mode) => mode === value);
4084
+ }
4085
+ function buildRcInterruptPayload(requestId) {
4086
+ return { type: "control_request", request_id: requestId, request: { subtype: "interrupt" } };
4087
+ }
4088
+ function buildRcSetModelPayload(requestId, model) {
4089
+ return { type: "control_request", request_id: requestId, request: { subtype: "set_model", model } };
4090
+ }
4091
+ function buildRcSetPermissionModePayload(requestId, mode) {
4092
+ return { type: "control_request", request_id: requestId, request: { subtype: "set_permission_mode", mode } };
4093
+ }
4073
4094
  async function answerRcControlRequest(deps, sessionId, requestId, decision) {
4074
4095
  const credential = deps.credentialOf(sessionId);
4075
4096
  if (credential === void 0) {
@@ -4094,9 +4115,64 @@ async function answerRcControlRequest(deps, sessionId, requestId, decision) {
4094
4115
  }
4095
4116
  return result;
4096
4117
  }
4118
+ async function interruptRcSession(deps, sessionId) {
4119
+ const credential = deps.credentialOf(sessionId);
4120
+ if (credential === void 0) {
4121
+ return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
4122
+ }
4123
+ if (credential.authorization === void 0) {
4124
+ return noOAuthCredentialResult(sessionId);
4125
+ }
4126
+ const body = JSON.stringify(buildRcEventWriteBody(buildRcInterruptPayload(deps.newUuid())));
4127
+ let answer;
4128
+ try {
4129
+ answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
4130
+ } catch (error) {
4131
+ return { ok: false, message: `the door could not reach the API host to interrupt session ${sessionId}: ${error instanceof Error ? error.message : String(error)}` };
4132
+ }
4133
+ return rcEventWriteResultFromAnswer(answer);
4134
+ }
4135
+ async function setRcSessionModel(deps, sessionId, model) {
4136
+ if (model === "") {
4137
+ return { ok: false, message: "a set-model write needs a non-empty model id: the SDK's own field treats an omitted or null value as a reset to the session default, which this operation never sends, and an empty string is neither" };
4138
+ }
4139
+ const credential = deps.credentialOf(sessionId);
4140
+ if (credential === void 0) {
4141
+ return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
4142
+ }
4143
+ if (credential.authorization === void 0) {
4144
+ return noOAuthCredentialResult(sessionId);
4145
+ }
4146
+ const body = JSON.stringify(buildRcEventWriteBody(buildRcSetModelPayload(deps.newUuid(), model)));
4147
+ let answer;
4148
+ try {
4149
+ answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
4150
+ } catch (error) {
4151
+ return { ok: false, message: `the door could not reach the API host to set the model on session ${sessionId}: ${error instanceof Error ? error.message : String(error)}` };
4152
+ }
4153
+ return rcEventWriteResultFromAnswer(answer);
4154
+ }
4155
+ async function setRcSessionPermissionMode(deps, sessionId, mode) {
4156
+ const credential = deps.credentialOf(sessionId);
4157
+ if (credential === void 0) {
4158
+ return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
4159
+ }
4160
+ if (credential.authorization === void 0) {
4161
+ return noOAuthCredentialResult(sessionId);
4162
+ }
4163
+ const body = JSON.stringify(buildRcEventWriteBody(buildRcSetPermissionModePayload(deps.newUuid(), mode)));
4164
+ let answer;
4165
+ try {
4166
+ answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
4167
+ } catch (error) {
4168
+ return { ok: false, message: `the door could not reach the API host to set the permission mode on session ${sessionId}: ${error instanceof Error ? error.message : String(error)}` };
4169
+ }
4170
+ return rcEventWriteResultFromAnswer(answer);
4171
+ }
4097
4172
 
4098
4173
  // src/frontdoor/rcControl.ts
4099
4174
  var https2 = __toESM(require("node:https"), 1);
4175
+ var RC_PERMISSION_MODE_LIST = RC_PERMISSION_MODES.join(", ");
4100
4176
  var CONTROL_PATH_PREFIX = "/__agent-shim/rc";
4101
4177
  var CONTROL_BODY_CAP_BYTES = 10485760;
4102
4178
  function answerJson(response, status, body) {
@@ -4131,6 +4207,9 @@ function createRcControlHandler(deps) {
4131
4207
  const pendingPath = `${CONTROL_PATH_PREFIX}/pending`;
4132
4208
  const injectPath = `${CONTROL_PATH_PREFIX}/inject`;
4133
4209
  const answerPath = `${CONTROL_PATH_PREFIX}/answer`;
4210
+ const interruptPath = `${CONTROL_PATH_PREFIX}/interrupt`;
4211
+ const setModelPath = `${CONTROL_PATH_PREFIX}/set-model`;
4212
+ const setPermissionModePath = `${CONTROL_PATH_PREFIX}/set-permission-mode`;
4134
4213
  return (request4, response) => {
4135
4214
  const presented = request4.headers.authorization;
4136
4215
  const bearerPrefix = "bearer ".length;
@@ -4215,6 +4294,78 @@ function createRcControlHandler(deps) {
4215
4294
  answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4216
4295
  return;
4217
4296
  }
4297
+ if (url.pathname === interruptPath) {
4298
+ if (request4.method !== "POST") {
4299
+ answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the interrupt operation is a POST" });
4300
+ return;
4301
+ }
4302
+ let parsed;
4303
+ try {
4304
+ parsed = JSON.parse(await readBody(request4));
4305
+ } catch {
4306
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the interrupt body is not readable JSON within the control body cap" });
4307
+ return;
4308
+ }
4309
+ if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || typeof parsed.session !== "string" || parsed.session === "") {
4310
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the interrupt body must be JSON naming a non-empty session id" });
4311
+ return;
4312
+ }
4313
+ const result = await deps.interrupt(parsed.session);
4314
+ if (result.ok) {
4315
+ answerJson(response, HTTP_STATUS.ok, { session: parsed.session, sequenceNums: result.sequenceNums });
4316
+ return;
4317
+ }
4318
+ answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4319
+ return;
4320
+ }
4321
+ if (url.pathname === setModelPath) {
4322
+ if (request4.method !== "POST") {
4323
+ answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the set-model operation is a POST" });
4324
+ return;
4325
+ }
4326
+ let parsed;
4327
+ try {
4328
+ parsed = JSON.parse(await readBody(request4));
4329
+ } catch {
4330
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the set-model body is not readable JSON within the control body cap" });
4331
+ return;
4332
+ }
4333
+ if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || !("model" in parsed) || typeof parsed.session !== "string" || typeof parsed.model !== "string" || parsed.session === "" || parsed.model === "") {
4334
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the set-model body must be JSON naming a non-empty session id and model id" });
4335
+ return;
4336
+ }
4337
+ const result = await deps.setModel(parsed.session, parsed.model);
4338
+ if (result.ok) {
4339
+ answerJson(response, HTTP_STATUS.ok, { session: parsed.session, model: parsed.model, sequenceNums: result.sequenceNums });
4340
+ return;
4341
+ }
4342
+ answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4343
+ return;
4344
+ }
4345
+ if (url.pathname === setPermissionModePath) {
4346
+ if (request4.method !== "POST") {
4347
+ answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the set-permission-mode operation is a POST" });
4348
+ return;
4349
+ }
4350
+ let parsed;
4351
+ try {
4352
+ parsed = JSON.parse(await readBody(request4));
4353
+ } catch {
4354
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the set-permission-mode body is not readable JSON within the control body cap" });
4355
+ return;
4356
+ }
4357
+ if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || !("mode" in parsed) || typeof parsed.session !== "string" || parsed.session === "" || !isRcPermissionMode(parsed.mode)) {
4358
+ answerJson(response, HTTP_STATUS.badRequest, { error: `the set-permission-mode body must be JSON naming a non-empty session id and a mode the SDK's own type permits (${RC_PERMISSION_MODE_LIST})` });
4359
+ return;
4360
+ }
4361
+ const result = await deps.setPermissionMode(parsed.session, parsed.mode);
4362
+ if (result.ok) {
4363
+ answerJson(response, HTTP_STATUS.ok, { session: parsed.session, mode: parsed.mode, sequenceNums: result.sequenceNums });
4364
+ return;
4365
+ }
4366
+ answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4367
+ return;
4368
+ }
4218
4369
  answerJson(response, HTTP_STATUS.notFound, { error: `no such control route: ${url.pathname}` });
4219
4370
  };
4220
4371
  handle().catch((error) => {
@@ -4429,7 +4580,10 @@ function frontDoorRcControl(transport, token) {
4429
4580
  `${CONTROL_PATH_PREFIX}/answer`,
4430
4581
  JSON.stringify({ session: sessionId, request: requestId, approve: decision.approve, ...decision.approve || decision.message === void 0 ? {} : { text: decision.message } }),
4431
4582
  (status, message) => `answering control request ${requestId} on ${sessionId} failed (HTTP ${String(status)}): ${message}`
4432
- )
4583
+ ),
4584
+ interruptSession: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/interrupt`, JSON.stringify({ session: sessionId }), (status, message) => `interrupting ${sessionId} failed (HTTP ${String(status)}): ${message}`),
4585
+ setModel: async (sessionId, model) => await writeOf(`${CONTROL_PATH_PREFIX}/set-model`, JSON.stringify({ session: sessionId, model }), (status, message) => `setting the model on ${sessionId} failed (HTTP ${String(status)}): ${message}`),
4586
+ setPermissionMode: async (sessionId, mode) => await writeOf(`${CONTROL_PATH_PREFIX}/set-permission-mode`, JSON.stringify({ session: sessionId, mode }), (status, message) => `setting the permission mode on ${sessionId} failed (HTTP ${String(status)}): ${message}`)
4433
4587
  };
4434
4588
  }
4435
4589
 
@@ -9379,6 +9533,7 @@ function prepareClaudeLaunch(options) {
9379
9533
  ProviderSchema,
9380
9534
  RC_IDLE_EXPIRY_MS,
9381
9535
  RC_PENDING_DEADLINE_MS,
9536
+ RC_PERMISSION_MODES,
9382
9537
  RC_REQUEST_PARSE_CAP_BYTES,
9383
9538
  RC_SESSIONS_PATH_PREFIX,
9384
9539
  ROUTED_PATH_PREFIX,
@@ -9395,6 +9550,9 @@ function prepareClaudeLaunch(options) {
9395
9550
  buildLayoutPaths,
9396
9551
  buildRcControlResponsePayload,
9397
9552
  buildRcEventWriteBody,
9553
+ buildRcInterruptPayload,
9554
+ buildRcSetModelPayload,
9555
+ buildRcSetPermissionModePayload,
9398
9556
  buildRcUserMessagePayload,
9399
9557
  carryOver,
9400
9558
  checkReportHasWarnings,
@@ -9419,8 +9577,10 @@ function prepareClaudeLaunch(options) {
9419
9577
  generateCa,
9420
9578
  identityExists,
9421
9579
  injectRcUserMessage,
9580
+ interruptRcSession,
9422
9581
  isIdentityDirectoryName,
9423
9582
  isInterceptedHost,
9583
+ isRcPermissionMode,
9424
9584
  listDirectoryRules,
9425
9585
  listIdentities,
9426
9586
  listProfiles,
@@ -9476,6 +9636,8 @@ function prepareClaudeLaunch(options) {
9476
9636
  setProfileEntries,
9477
9637
  setProfileLaunchFlags,
9478
9638
  setProfileMetadata,
9639
+ setRcSessionModel,
9640
+ setRcSessionPermissionMode,
9479
9641
  snapshotPath,
9480
9642
  startConnectServer,
9481
9643
  topLevelNames,
package/dist/index.mjs CHANGED
@@ -3886,6 +3886,19 @@ function buildRcControlResponsePayload(requestId, decision) {
3886
3886
  const result = decision.approve ? { behavior: "allow" } : { behavior: "deny", message: decision.message ?? "" };
3887
3887
  return { type: "control_response", response: { subtype: "success", request_id: requestId, response: result } };
3888
3888
  }
3889
+ var RC_PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"];
3890
+ function isRcPermissionMode(value) {
3891
+ return RC_PERMISSION_MODES.some((mode) => mode === value);
3892
+ }
3893
+ function buildRcInterruptPayload(requestId) {
3894
+ return { type: "control_request", request_id: requestId, request: { subtype: "interrupt" } };
3895
+ }
3896
+ function buildRcSetModelPayload(requestId, model) {
3897
+ return { type: "control_request", request_id: requestId, request: { subtype: "set_model", model } };
3898
+ }
3899
+ function buildRcSetPermissionModePayload(requestId, mode) {
3900
+ return { type: "control_request", request_id: requestId, request: { subtype: "set_permission_mode", mode } };
3901
+ }
3889
3902
  async function answerRcControlRequest(deps, sessionId, requestId, decision) {
3890
3903
  const credential = deps.credentialOf(sessionId);
3891
3904
  if (credential === void 0) {
@@ -3910,9 +3923,64 @@ async function answerRcControlRequest(deps, sessionId, requestId, decision) {
3910
3923
  }
3911
3924
  return result;
3912
3925
  }
3926
+ async function interruptRcSession(deps, sessionId) {
3927
+ const credential = deps.credentialOf(sessionId);
3928
+ if (credential === void 0) {
3929
+ return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
3930
+ }
3931
+ if (credential.authorization === void 0) {
3932
+ return noOAuthCredentialResult(sessionId);
3933
+ }
3934
+ const body = JSON.stringify(buildRcEventWriteBody(buildRcInterruptPayload(deps.newUuid())));
3935
+ let answer;
3936
+ try {
3937
+ answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
3938
+ } catch (error) {
3939
+ return { ok: false, message: `the door could not reach the API host to interrupt session ${sessionId}: ${error instanceof Error ? error.message : String(error)}` };
3940
+ }
3941
+ return rcEventWriteResultFromAnswer(answer);
3942
+ }
3943
+ async function setRcSessionModel(deps, sessionId, model) {
3944
+ if (model === "") {
3945
+ return { ok: false, message: "a set-model write needs a non-empty model id: the SDK's own field treats an omitted or null value as a reset to the session default, which this operation never sends, and an empty string is neither" };
3946
+ }
3947
+ const credential = deps.credentialOf(sessionId);
3948
+ if (credential === void 0) {
3949
+ return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
3950
+ }
3951
+ if (credential.authorization === void 0) {
3952
+ return noOAuthCredentialResult(sessionId);
3953
+ }
3954
+ const body = JSON.stringify(buildRcEventWriteBody(buildRcSetModelPayload(deps.newUuid(), model)));
3955
+ let answer;
3956
+ try {
3957
+ answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
3958
+ } catch (error) {
3959
+ return { ok: false, message: `the door could not reach the API host to set the model on session ${sessionId}: ${error instanceof Error ? error.message : String(error)}` };
3960
+ }
3961
+ return rcEventWriteResultFromAnswer(answer);
3962
+ }
3963
+ async function setRcSessionPermissionMode(deps, sessionId, mode) {
3964
+ const credential = deps.credentialOf(sessionId);
3965
+ if (credential === void 0) {
3966
+ return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
3967
+ }
3968
+ if (credential.authorization === void 0) {
3969
+ return noOAuthCredentialResult(sessionId);
3970
+ }
3971
+ const body = JSON.stringify(buildRcEventWriteBody(buildRcSetPermissionModePayload(deps.newUuid(), mode)));
3972
+ let answer;
3973
+ try {
3974
+ answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
3975
+ } catch (error) {
3976
+ return { ok: false, message: `the door could not reach the API host to set the permission mode on session ${sessionId}: ${error instanceof Error ? error.message : String(error)}` };
3977
+ }
3978
+ return rcEventWriteResultFromAnswer(answer);
3979
+ }
3913
3980
 
3914
3981
  // src/frontdoor/rcControl.ts
3915
3982
  import * as https2 from "node:https";
3983
+ var RC_PERMISSION_MODE_LIST = RC_PERMISSION_MODES.join(", ");
3916
3984
  var CONTROL_PATH_PREFIX = "/__agent-shim/rc";
3917
3985
  var CONTROL_BODY_CAP_BYTES = 10485760;
3918
3986
  function answerJson(response, status, body) {
@@ -3947,6 +4015,9 @@ function createRcControlHandler(deps) {
3947
4015
  const pendingPath = `${CONTROL_PATH_PREFIX}/pending`;
3948
4016
  const injectPath = `${CONTROL_PATH_PREFIX}/inject`;
3949
4017
  const answerPath = `${CONTROL_PATH_PREFIX}/answer`;
4018
+ const interruptPath = `${CONTROL_PATH_PREFIX}/interrupt`;
4019
+ const setModelPath = `${CONTROL_PATH_PREFIX}/set-model`;
4020
+ const setPermissionModePath = `${CONTROL_PATH_PREFIX}/set-permission-mode`;
3950
4021
  return (request4, response) => {
3951
4022
  const presented = request4.headers.authorization;
3952
4023
  const bearerPrefix = "bearer ".length;
@@ -4031,6 +4102,78 @@ function createRcControlHandler(deps) {
4031
4102
  answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4032
4103
  return;
4033
4104
  }
4105
+ if (url.pathname === interruptPath) {
4106
+ if (request4.method !== "POST") {
4107
+ answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the interrupt operation is a POST" });
4108
+ return;
4109
+ }
4110
+ let parsed;
4111
+ try {
4112
+ parsed = JSON.parse(await readBody(request4));
4113
+ } catch {
4114
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the interrupt body is not readable JSON within the control body cap" });
4115
+ return;
4116
+ }
4117
+ if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || typeof parsed.session !== "string" || parsed.session === "") {
4118
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the interrupt body must be JSON naming a non-empty session id" });
4119
+ return;
4120
+ }
4121
+ const result = await deps.interrupt(parsed.session);
4122
+ if (result.ok) {
4123
+ answerJson(response, HTTP_STATUS.ok, { session: parsed.session, sequenceNums: result.sequenceNums });
4124
+ return;
4125
+ }
4126
+ answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4127
+ return;
4128
+ }
4129
+ if (url.pathname === setModelPath) {
4130
+ if (request4.method !== "POST") {
4131
+ answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the set-model operation is a POST" });
4132
+ return;
4133
+ }
4134
+ let parsed;
4135
+ try {
4136
+ parsed = JSON.parse(await readBody(request4));
4137
+ } catch {
4138
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the set-model body is not readable JSON within the control body cap" });
4139
+ return;
4140
+ }
4141
+ if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || !("model" in parsed) || typeof parsed.session !== "string" || typeof parsed.model !== "string" || parsed.session === "" || parsed.model === "") {
4142
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the set-model body must be JSON naming a non-empty session id and model id" });
4143
+ return;
4144
+ }
4145
+ const result = await deps.setModel(parsed.session, parsed.model);
4146
+ if (result.ok) {
4147
+ answerJson(response, HTTP_STATUS.ok, { session: parsed.session, model: parsed.model, sequenceNums: result.sequenceNums });
4148
+ return;
4149
+ }
4150
+ answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4151
+ return;
4152
+ }
4153
+ if (url.pathname === setPermissionModePath) {
4154
+ if (request4.method !== "POST") {
4155
+ answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the set-permission-mode operation is a POST" });
4156
+ return;
4157
+ }
4158
+ let parsed;
4159
+ try {
4160
+ parsed = JSON.parse(await readBody(request4));
4161
+ } catch {
4162
+ answerJson(response, HTTP_STATUS.badRequest, { error: "the set-permission-mode body is not readable JSON within the control body cap" });
4163
+ return;
4164
+ }
4165
+ if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || !("mode" in parsed) || typeof parsed.session !== "string" || parsed.session === "" || !isRcPermissionMode(parsed.mode)) {
4166
+ answerJson(response, HTTP_STATUS.badRequest, { error: `the set-permission-mode body must be JSON naming a non-empty session id and a mode the SDK's own type permits (${RC_PERMISSION_MODE_LIST})` });
4167
+ return;
4168
+ }
4169
+ const result = await deps.setPermissionMode(parsed.session, parsed.mode);
4170
+ if (result.ok) {
4171
+ answerJson(response, HTTP_STATUS.ok, { session: parsed.session, mode: parsed.mode, sequenceNums: result.sequenceNums });
4172
+ return;
4173
+ }
4174
+ answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
4175
+ return;
4176
+ }
4034
4177
  answerJson(response, HTTP_STATUS.notFound, { error: `no such control route: ${url.pathname}` });
4035
4178
  };
4036
4179
  handle().catch((error) => {
@@ -4245,7 +4388,10 @@ function frontDoorRcControl(transport, token) {
4245
4388
  `${CONTROL_PATH_PREFIX}/answer`,
4246
4389
  JSON.stringify({ session: sessionId, request: requestId, approve: decision.approve, ...decision.approve || decision.message === void 0 ? {} : { text: decision.message } }),
4247
4390
  (status, message) => `answering control request ${requestId} on ${sessionId} failed (HTTP ${String(status)}): ${message}`
4248
- )
4391
+ ),
4392
+ interruptSession: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/interrupt`, JSON.stringify({ session: sessionId }), (status, message) => `interrupting ${sessionId} failed (HTTP ${String(status)}): ${message}`),
4393
+ setModel: async (sessionId, model) => await writeOf(`${CONTROL_PATH_PREFIX}/set-model`, JSON.stringify({ session: sessionId, model }), (status, message) => `setting the model on ${sessionId} failed (HTTP ${String(status)}): ${message}`),
4394
+ setPermissionMode: async (sessionId, mode) => await writeOf(`${CONTROL_PATH_PREFIX}/set-permission-mode`, JSON.stringify({ session: sessionId, mode }), (status, message) => `setting the permission mode on ${sessionId} failed (HTTP ${String(status)}): ${message}`)
4249
4395
  };
4250
4396
  }
4251
4397
 
@@ -9194,6 +9340,7 @@ export {
9194
9340
  ProviderSchema,
9195
9341
  RC_IDLE_EXPIRY_MS,
9196
9342
  RC_PENDING_DEADLINE_MS,
9343
+ RC_PERMISSION_MODES,
9197
9344
  RC_REQUEST_PARSE_CAP_BYTES,
9198
9345
  RC_SESSIONS_PATH_PREFIX,
9199
9346
  ROUTED_PATH_PREFIX,
@@ -9210,6 +9357,9 @@ export {
9210
9357
  buildLayoutPaths,
9211
9358
  buildRcControlResponsePayload,
9212
9359
  buildRcEventWriteBody,
9360
+ buildRcInterruptPayload,
9361
+ buildRcSetModelPayload,
9362
+ buildRcSetPermissionModePayload,
9213
9363
  buildRcUserMessagePayload,
9214
9364
  carryOver,
9215
9365
  checkReportHasWarnings,
@@ -9234,8 +9384,10 @@ export {
9234
9384
  generateCa,
9235
9385
  identityExists,
9236
9386
  injectRcUserMessage,
9387
+ interruptRcSession,
9237
9388
  isIdentityDirectoryName,
9238
9389
  isInterceptedHost,
9390
+ isRcPermissionMode,
9239
9391
  listDirectoryRules,
9240
9392
  listIdentities,
9241
9393
  listProfiles,
@@ -9291,6 +9443,8 @@ export {
9291
9443
  setProfileEntries,
9292
9444
  setProfileLaunchFlags,
9293
9445
  setProfileMetadata,
9446
+ setRcSessionModel,
9447
+ setRcSessionPermissionMode,
9294
9448
  snapshotPath,
9295
9449
  startConnectServer,
9296
9450
  topLevelNames,
@@ -1662,11 +1662,11 @@ interface FrontDoorRoute {
1662
1662
  }
1663
1663
 
1664
1664
  /**
1665
- * Remote Control session tracking and the client-half writes the front door performs: the record of the `cse_` sessions whose traffic crosses its terminated API-host session, the prompt injected into one, and the answer delivered to one of its pending control requests.
1665
+ * Remote Control session tracking and the client-half writes the front door performs: the record of the `cse_` sessions whose traffic crosses its terminated API-host session, the prompt injected into one, the answer delivered to one of its pending control requests, and the client-originated control requests sent into one (interrupt, set_model, set_permission_mode).
1666
1666
  *
1667
1667
  * The tracker is observational: the door already terminates the API host's TLS, so it sees the CLI's own `POST /v1/code/sessions` (whose answer carries the new session's `cse_` id) and every recurring `/v1/code/sessions/...` call (heartbeat, presence), each carrying the session's Authorization bearer and the protocol headers a client-half replay needs. Per session the tracker retains the latest of each, because those calls recur and the freshest value is the live one. It also reads the request bodies of the exchanges whose payloads matter: the worker's event batches (whose `control_request` payloads, `can_use_tool` above all, are the approvals awaiting an answer), the worker heartbeats (whose bodies carry `idle_seconds`), the worker registration (whose body carries the worker state), and the client-half event writes (whose `control_response` payloads complete a pending request). Everything is held in this process's memory only: nothing here is written to a log, to the capture, or to disk, and the summary the control surface lists never includes the credential. The capture's existing redaction is untouched; a capture and this tracker observe the same exchanges through entirely separate paths.
1668
1668
  *
1669
- * Both writes replay the protocol's documented client half rather than splicing frames into any relayed stream: `POST /v1/code/sessions/{id}/events` with one payload event (a user message, or a `control_response` answering an observed request by echoing its id), authenticated by the observed bearer and the observed protocol headers, sent from the door over its own interception-proof dials. Sequence numbers therefore come from the real service and the event is mirrored to every attached client, exactly as a message typed into claude.ai would be.
1669
+ * Every write replays the protocol's documented client half rather than splicing frames into any relayed stream: `POST /v1/code/sessions/{id}/events` with one payload event (a user message, a `control_response` answering an observed request by echoing its id, or a `control_request` a client originates), authenticated by the observed bearer and the observed protocol headers, sent from the door over its own interception-proof dials. Sequence numbers therefore come from the real service and the event is mirrored to every attached client, exactly as a message typed into claude.ai would be.
1670
1670
  */
1671
1671
  /** Every Remote Control exchange on the API host sits under this path prefix. */
1672
1672
  declare const RC_SESSIONS_PATH_PREFIX = "/v1/code/sessions";
@@ -1819,6 +1819,26 @@ interface RcAnswerDecision {
1819
1819
  * Builds the `control_response` payload event for one answer: the SDK's response envelope, `subtype: "success"` with the request's id echoed in `request_id`, carrying the permission result the worker is waiting for (`behavior: "allow"`, or `"deny"` with its message).
1820
1820
  */
1821
1821
  declare function buildRcControlResponsePayload(requestId: string, decision: RcAnswerDecision): Record<string, unknown>;
1822
+ /**
1823
+ * The permission modes the SDK's own `set_permission_mode` control request accepts: exactly the strings its `PermissionMode` type declares (`@anthropic-ai/claude-agent-sdk` `sdk.d.ts`), nothing looser. A runtime list as well as a type, because the CLI and the control route both narrow untrusted strings through it before a write is ever attempted.
1824
+ */
1825
+ declare const RC_PERMISSION_MODES: readonly ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"];
1826
+ /** One permission mode the SDK's `set_permission_mode` control request accepts. */
1827
+ type RcPermissionMode = (typeof RC_PERMISSION_MODES)[number];
1828
+ /** Whether a value is one of the SDK's own permission modes, the narrowing the CLI and the control route apply to untrusted input. */
1829
+ declare function isRcPermissionMode(value: unknown): value is RcPermissionMode;
1830
+ /**
1831
+ * Builds the `control_request` payload event for one interrupt: the SDK's request envelope (`SDKControlRequest`: `type`, `request_id`, `request`), carrying the `interrupt` subtype's own shape (`subtype` alone; its optional `cancel_queued` is absent, which the SDK reads as false, so queued commands survive the interrupt exactly as a plain stop button's would). The request id is the caller's minted uuid, the id the worker's `control_response` echoes.
1832
+ */
1833
+ declare function buildRcInterruptPayload(requestId: string): Record<string, unknown>;
1834
+ /**
1835
+ * Builds the `control_request` payload event for one model switch: the SDK's request envelope carrying the `set_model` subtype's own shape, whose one field is the `model` id string (its omitted and null forms mean a reset to the session default, which this builder never sends; the operation refuses an empty id for the same reason).
1836
+ */
1837
+ declare function buildRcSetModelPayload(requestId: string, model: string): Record<string, unknown>;
1838
+ /**
1839
+ * Builds the `control_request` payload event for one permission-mode change: the SDK's request envelope carrying the `set_permission_mode` subtype's own shape, whose one field is the `mode` from the SDK's own `PermissionMode` enum (`RC_PERMISSION_MODES`).
1840
+ */
1841
+ declare function buildRcSetPermissionModePayload(requestId: string, mode: RcPermissionMode): Record<string, unknown>;
1822
1842
  /** Everything one answer needs, injected so the decision logic runs against fakes in unit tests. */
1823
1843
  interface RcAnswerDeps {
1824
1844
  /** Reads the observed credential for a session: the tracker's accessor, in production. */
@@ -1834,6 +1854,27 @@ interface RcAnswerDeps {
1834
1854
  * Answers one pending control request on an observed session: the same documented client-half write the inject path performs, carrying a `control_response` that echoes the request's id, authenticated by the observed bearer and protocol headers. The request must still be pending (an answered or deadline-expired request is refused verbosely, since writing a response nothing waits for would mislead the caller), and a successful write retires it. A dial that cannot reach the API host is reported rather than thrown.
1835
1855
  */
1836
1856
  declare function answerRcControlRequest(deps: RcAnswerDeps, sessionId: string, requestId: string, decision: RcAnswerDecision): Promise<RcEventWriteResult>;
1857
+ /** Everything one client-originated control request needs, injected so the decision logic runs against fakes in unit tests. */
1858
+ interface RcControlRequestDeps {
1859
+ /** Reads the observed credential for a session: the tracker's accessor, in production. */
1860
+ readonly credentialOf: (sessionId: string) => RcObservedCredential | undefined;
1861
+ /** The dial to the real API host. */
1862
+ readonly dial: RcEventDial;
1863
+ /** Mints the request's id: a v4 UUID or better in production, the id the worker's `control_response` echoes. */
1864
+ readonly newUuid: () => string;
1865
+ }
1866
+ /**
1867
+ * Interrupts one observed session's running turn: the same documented client-half write the inject and answer paths perform, carrying the SDK's `control_request` envelope for the `interrupt` subtype, authenticated by the observed bearer and protocol headers. The result is the sequence numbers the real service assigned, or a verbose failure. A dial that cannot reach the API host is reported rather than thrown, so a caller with no exception handling still shows the user exactly what failed.
1868
+ */
1869
+ declare function interruptRcSession(deps: RcControlRequestDeps, sessionId: string): Promise<RcEventWriteResult>;
1870
+ /**
1871
+ * Sets the model one observed session's subsequent turns use: the same documented client-half write the inject and answer paths perform, carrying the SDK's `control_request` envelope for the `set_model` subtype with the model id its own field names. The id is validated only as non-empty, because the SDK's field gives the empty-free forms their own meaning (omitted or null resets to the session default) and this operation sends neither. The result is the sequence numbers the real service assigned, or a verbose failure.
1872
+ */
1873
+ declare function setRcSessionModel(deps: RcControlRequestDeps, sessionId: string, model: string): Promise<RcEventWriteResult>;
1874
+ /**
1875
+ * Sets one observed session's permission mode: the same documented client-half write the inject and answer paths perform, carrying the SDK's `control_request` envelope for the `set_permission_mode` subtype with a mode from the SDK's own enum (`RC_PERMISSION_MODES`; the type accepts nothing looser, and the CLI and control route narrow untrusted strings through `isRcPermissionMode` before they ever reach this operation). The result is the sequence numbers the real service assigned, or a verbose failure.
1876
+ */
1877
+ declare function setRcSessionPermissionMode(deps: RcControlRequestDeps, sessionId: string, mode: RcPermissionMode): Promise<RcEventWriteResult>;
1837
1878
 
1838
1879
  /** Where the Remote Control inject path dials: the API host's own address by default, over TLS with the door's interception-proof agent (real-name DNS resolution and the pf-exempt source-port range), so an injected event cannot be looped back into the door's own transparent surface. A test redirects the dial at a local stand-in presenting the host's name, exactly as the forwarding targets are redirected. */
1839
1880
  interface RcDialTarget {
@@ -1853,9 +1894,9 @@ declare function realRcEventDial(target?: RcDialTarget): RcEventDial;
1853
1894
  declare function realConnectEffects(): ConnectEffects;
1854
1895
 
1855
1896
  /**
1856
- * The Remote Control control surface: the small HTTP namespace the serving door answers on its provider listener, next to `/healthz`, through which `agent-shim frontdoor rc` lists the observed sessions, reports each one's status and pending control requests, injects a prompt into one, and answers one of its pending requests.
1897
+ * The Remote Control control surface: the small HTTP namespace the serving door answers on its provider listener, next to `/healthz`, through which `agent-shim frontdoor rc` lists the observed sessions, reports each one's status and pending control requests, injects a prompt into one, answers one of its pending requests, and sends its own control requests into one (interrupt, set-model, set-permission-mode).
1857
1898
  *
1858
- * This rides the listener `frontdoor status` already knows the door by (its address comes from the same state file, its trust anchor from the same CA path) rather than any second channel. The routes sit under one prefix the routed pipeline never serves, and every request must present the serving generation's control token as a Bearer credential: a fresh random value per door start, written owner-only under the front door's state directory so only this user's CLI can read it, and checked in constant time like every other capability the door accepts. An inject or answer request is carried out by the door itself over its interception-proof dials, which is the whole point: the CLI never dials the API host directly, so nothing about the write depends on the caller's own network path.
1899
+ * This rides the listener `frontdoor status` already knows the door by (its address comes from the same state file, its trust anchor from the same CA path) rather than any second channel. The routes sit under one prefix the routed pipeline never serves, and every request must present the serving generation's control token as a Bearer credential: a fresh random value per door start, written owner-only under the front door's state directory so only this user's CLI can read it, and checked in constant time like every other capability the door accepts. An inject, answer or control request is carried out by the door itself over its interception-proof dials, which is the whole point: the CLI never dials the API host directly, so nothing about the write depends on the caller's own network path.
1859
1900
  */
1860
1901
  /** The one path prefix every Remote Control control route sits under, answered before the routed pipeline like `/healthz` is. */
1861
1902
  declare const CONTROL_PATH_PREFIX = "/__agent-shim/rc";
@@ -1873,6 +1914,12 @@ interface RcControlHandlerDeps {
1873
1914
  readonly inject: (sessionId: string, text: string) => Promise<RcEventWriteResult>;
1874
1915
  /** The answer operation, already wired to the tracker and the door's API-host dial. */
1875
1916
  readonly answer: (sessionId: string, requestId: string, decision: RcAnswerDecision) => Promise<RcEventWriteResult>;
1917
+ /** The interrupt operation, already wired to the tracker and the door's API-host dial. */
1918
+ readonly interrupt: (sessionId: string) => Promise<RcEventWriteResult>;
1919
+ /** The set-model operation, already wired to the tracker and the door's API-host dial. */
1920
+ readonly setModel: (sessionId: string, model: string) => Promise<RcEventWriteResult>;
1921
+ /** The set-permission-mode operation, already wired to the tracker and the door's API-host dial. */
1922
+ readonly setPermissionMode: (sessionId: string, mode: RcPermissionMode) => Promise<RcEventWriteResult>;
1876
1923
  }
1877
1924
  /**
1878
1925
  * Builds the control handler the provider listener serves under `CONTROL_PATH_PREFIX`. Every route demands the generation's control token first, so nothing about the sessions (their ids, their timing, and most of all the prompts and approvals carried into them) is reachable by a process that did not read the owner-only token file.
@@ -1894,7 +1941,7 @@ interface RcControlTransport {
1894
1941
  }
1895
1942
  /** The real transport: HTTPS to the door's provider listener on loopback, trusting only the CA file the door's own state names, so a process merely holding the port cannot answer as the door. */
1896
1943
  declare function realRcControlTransport(port: number, ca: string): RcControlTransport;
1897
- /** The door-facing client the `frontdoor rc` verbs use: the session list, the status and pending reads, and the inject and answer operations, over the injected transport. */
1944
+ /** The door-facing client the `frontdoor rc` verbs use: the session list, the status and pending reads, the inject and answer operations, and the door's own control requests (interrupt, set-model, set-permission-mode), over the injected transport. */
1898
1945
  interface FrontDoorRcControl {
1899
1946
  /** The observed sessions, oldest-created first. Throws with the door's verbose reason when the list cannot be had. */
1900
1947
  readonly listSessions: () => Promise<readonly RcSessionSummary[]>;
@@ -1906,6 +1953,12 @@ interface FrontDoorRcControl {
1906
1953
  readonly sendPrompt: (sessionId: string, text: string) => Promise<RcEventWriteResult>;
1907
1954
  /** Answers one pending control request, returning the sequence numbers the real service assigned or the verbose failure. */
1908
1955
  readonly answerRequest: (sessionId: string, requestId: string, decision: RcAnswerDecision) => Promise<RcEventWriteResult>;
1956
+ /** Interrupts one session's running turn, returning the sequence numbers the real service assigned or the verbose failure. */
1957
+ readonly interruptSession: (sessionId: string) => Promise<RcEventWriteResult>;
1958
+ /** Sets the model one session's subsequent turns use, returning the sequence numbers the real service assigned or the verbose failure. */
1959
+ readonly setModel: (sessionId: string, model: string) => Promise<RcEventWriteResult>;
1960
+ /** Sets one session's permission mode, returning the sequence numbers the real service assigned or the verbose failure. */
1961
+ readonly setPermissionMode: (sessionId: string, mode: RcPermissionMode) => Promise<RcEventWriteResult>;
1909
1962
  }
1910
1963
  /** Builds the control client: every request presents the control token, and a non-2xx answer becomes the verbose message the door sent with it. */
1911
1964
  declare function frontDoorRcControl(transport: RcControlTransport, token: string): FrontDoorRcControl;
@@ -3131,5 +3184,5 @@ interface PrepareClaudeLaunchOptions {
3131
3184
  */
3132
3185
  declare function prepareClaudeLaunch(options: PrepareClaudeLaunchOptions): LaunchPlan;
3133
3186
 
3134
- export { AMBIENT_CREDENTIAL_VARS, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, EXIT_FAILURE, EXIT_USAGE, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorStartError, GlobalConfigSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LaunchRefusedError, LegacyProviderFileError, PoolNameSchema, PoolNotFoundError, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_IDLE_EXPIRY_MS, RC_PENDING_DEADLINE_MS, RC_REQUEST_PARSE_CAP_BYTES, RC_SESSIONS_PATH_PREFIX, ROUTED_PATH_PREFIX, UsageError, UsageSnapshotError, UsageSnapshotSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, buildEntryFacts, buildLayoutPaths, buildRcControlResponsePayload, buildRcEventWriteBody, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, createLeafCache, createProfile, createRcControlHandler, createRcSessionTracker, describeProviderEndpoint, detectAmbientCredential, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, forwardableHeaders, frontDoorRcControl, generateCa, identityExists, injectRcUserMessage, isIdentityDirectoryName, isInterceptedHost, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, mintLeaf, observingRoutedRoute, parseConnectTarget, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rcEventWriteResultFromAnswer, rcObserverAsPassthrough, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runSupervisor, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, snapshotPath, startConnectServer, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
3135
- export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectServerConfig, ConnectServerHandle, ConnectTarget, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, Pool, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RcAnswerDecision, RcAnswerDeps, RcControlAnswer, RcControlHandlerDeps, RcControlTransport, RcDialAnswer, RcDialTarget, RcEventDial, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunSupervisorOptions, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition };
3187
+ export { AMBIENT_CREDENTIAL_VARS, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, EXIT_FAILURE, EXIT_USAGE, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorStartError, GlobalConfigSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LaunchRefusedError, LegacyProviderFileError, PoolNameSchema, PoolNotFoundError, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_IDLE_EXPIRY_MS, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_REQUEST_PARSE_CAP_BYTES, RC_SESSIONS_PATH_PREFIX, ROUTED_PATH_PREFIX, UsageError, UsageSnapshotError, UsageSnapshotSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, buildEntryFacts, buildLayoutPaths, buildRcControlResponsePayload, buildRcEventWriteBody, buildRcInterruptPayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, createLeafCache, createProfile, createRcControlHandler, createRcSessionTracker, describeProviderEndpoint, detectAmbientCredential, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, forwardableHeaders, frontDoorRcControl, generateCa, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isRcPermissionMode, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, mintLeaf, observingRoutedRoute, parseConnectTarget, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rcEventWriteResultFromAnswer, rcObserverAsPassthrough, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runSupervisor, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, startConnectServer, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
3188
+ export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectServerConfig, ConnectServerHandle, ConnectTarget, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, Pool, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RcAnswerDecision, RcAnswerDeps, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcDialAnswer, RcDialTarget, RcEventDial, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunSupervisorOptions, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "8.5.6",
3
+ "version": "8.6.0",
4
4
  "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.",
5
5
  "license": "MIT",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",