agent-shim 8.23.0 → 8.24.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/README.md +10 -0
- package/dist/cli.cjs +2171 -1810
- package/dist/index.cjs +423 -100
- package/dist/index.mjs +398 -100
- package/dist/types/index.d.ts +371 -13
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -93,10 +93,12 @@ __export(index_exports, {
|
|
|
93
93
|
ProviderKindMismatchError: () => ProviderKindMismatchError,
|
|
94
94
|
ProviderNotFoundError: () => ProviderNotFoundError,
|
|
95
95
|
ProviderSchema: () => ProviderSchema,
|
|
96
|
+
RC_CONTEXT_USAGE_DETAILS: () => RC_CONTEXT_USAGE_DETAILS,
|
|
96
97
|
RC_IDLE_EXPIRY_MS: () => RC_IDLE_EXPIRY_MS,
|
|
97
98
|
RC_ORPC_PATH_PREFIX: () => RC_ORPC_PATH_PREFIX,
|
|
98
99
|
RC_PENDING_DEADLINE_MS: () => RC_PENDING_DEADLINE_MS,
|
|
99
100
|
RC_PERMISSION_MODES: () => RC_PERMISSION_MODES,
|
|
101
|
+
RC_READ_FILE_ENCODINGS: () => RC_READ_FILE_ENCODINGS,
|
|
100
102
|
RC_REQUEST_PARSE_CAP_BYTES: () => RC_REQUEST_PARSE_CAP_BYTES,
|
|
101
103
|
RC_SELF_HOST_ENV: () => RC_SELF_HOST_ENV,
|
|
102
104
|
RC_SELF_HOST_KEEPALIVE_MS: () => RC_SELF_HOST_KEEPALIVE_MS,
|
|
@@ -127,11 +129,23 @@ __export(index_exports, {
|
|
|
127
129
|
addPool: () => addPool,
|
|
128
130
|
addProvider: () => addProvider,
|
|
129
131
|
answerRcControlRequest: () => answerRcControlRequest,
|
|
132
|
+
authenticateRcSessionMcpServer: () => authenticateRcSessionMcpServer,
|
|
130
133
|
buildEntryFacts: () => buildEntryFacts,
|
|
131
134
|
buildLayoutPaths: () => buildLayoutPaths,
|
|
135
|
+
buildRcControlRequestPayload: () => buildRcControlRequestPayload,
|
|
132
136
|
buildRcControlResponsePayload: () => buildRcControlResponsePayload,
|
|
137
|
+
buildRcEndSessionPayload: () => buildRcEndSessionPayload,
|
|
133
138
|
buildRcEventWriteBody: () => buildRcEventWriteBody,
|
|
139
|
+
buildRcFileSuggestionsPayload: () => buildRcFileSuggestionsPayload,
|
|
140
|
+
buildRcGetContextUsagePayload: () => buildRcGetContextUsagePayload,
|
|
141
|
+
buildRcGetUsagePayload: () => buildRcGetUsagePayload,
|
|
134
142
|
buildRcInterruptPayload: () => buildRcInterruptPayload,
|
|
143
|
+
buildRcKeepAlivePayload: () => buildRcKeepAlivePayload,
|
|
144
|
+
buildRcMcpAuthenticatePayload: () => buildRcMcpAuthenticatePayload,
|
|
145
|
+
buildRcMcpOAuthCallbackUrlPayload: () => buildRcMcpOAuthCallbackUrlPayload,
|
|
146
|
+
buildRcMcpReconnectPayload: () => buildRcMcpReconnectPayload,
|
|
147
|
+
buildRcMcpStatusPayload: () => buildRcMcpStatusPayload,
|
|
148
|
+
buildRcReadFilePayload: () => buildRcReadFilePayload,
|
|
135
149
|
buildRcSetModelPayload: () => buildRcSetModelPayload,
|
|
136
150
|
buildRcSetPermissionModePayload: () => buildRcSetPermissionModePayload,
|
|
137
151
|
buildRcUserMessagePayload: () => buildRcUserMessagePayload,
|
|
@@ -164,6 +178,7 @@ __export(index_exports, {
|
|
|
164
178
|
doorApiAuth: () => doorApiAuth,
|
|
165
179
|
doorApiNodeHandlerOf: () => doorApiNodeHandlerOf,
|
|
166
180
|
effectiveWindow: () => effectiveWindow,
|
|
181
|
+
endRcSession: () => endRcSession,
|
|
167
182
|
ensureCa: () => ensureCa,
|
|
168
183
|
ensureFrontDoor: () => ensureFrontDoor,
|
|
169
184
|
ensureHeadroom: () => ensureHeadroom,
|
|
@@ -180,6 +195,9 @@ __export(index_exports, {
|
|
|
180
195
|
frontDoorRcApiClient: () => frontDoorRcApiClient,
|
|
181
196
|
frontDoorRcControl: () => frontDoorRcControl,
|
|
182
197
|
generateCa: () => generateCa,
|
|
198
|
+
getRcSessionContextUsage: () => getRcSessionContextUsage,
|
|
199
|
+
getRcSessionMcpStatus: () => getRcSessionMcpStatus,
|
|
200
|
+
getRcSessionUsage: () => getRcSessionUsage,
|
|
183
201
|
headroomSocketTarget: () => headroomSocketTarget,
|
|
184
202
|
identityExists: () => identityExists,
|
|
185
203
|
injectRcUserMessage: () => injectRcUserMessage,
|
|
@@ -187,7 +205,9 @@ __export(index_exports, {
|
|
|
187
205
|
isIdentityDirectoryName: () => isIdentityDirectoryName,
|
|
188
206
|
isInterceptedHost: () => isInterceptedHost,
|
|
189
207
|
isPrivateAddress: () => isPrivateAddress,
|
|
208
|
+
isRcContextUsageDetail: () => isRcContextUsageDetail,
|
|
190
209
|
isRcPermissionMode: () => isRcPermissionMode,
|
|
210
|
+
isRcReadFileEncoding: () => isRcReadFileEncoding,
|
|
191
211
|
lateRcEventDial: () => lateRcEventDial,
|
|
192
212
|
lateRcStreamDial: () => lateRcStreamDial,
|
|
193
213
|
listDirectoryRules: () => listDirectoryRules,
|
|
@@ -221,6 +241,7 @@ __export(index_exports, {
|
|
|
221
241
|
readProfile: () => readProfile,
|
|
222
242
|
readProvider: () => readProvider,
|
|
223
243
|
readRcSelfHostRecord: () => readRcSelfHostRecord,
|
|
244
|
+
readRcSessionFile: () => readRcSessionFile,
|
|
224
245
|
readUsageSnapshot: () => readUsageSnapshot,
|
|
225
246
|
realConnectCertStore: () => realConnectCertStore,
|
|
226
247
|
realConnectEffects: () => realConnectEffects,
|
|
@@ -228,6 +249,7 @@ __export(index_exports, {
|
|
|
228
249
|
realRcEventDial: () => realRcEventDial,
|
|
229
250
|
realRcStreamDial: () => realRcStreamDial,
|
|
230
251
|
realRcWebFetch: () => realRcWebFetch,
|
|
252
|
+
reconnectRcSessionMcpServer: () => reconnectRcSessionMcpServer,
|
|
231
253
|
recoverFarm: () => recoverFarm,
|
|
232
254
|
recoveryDiagnostics: () => recoveryDiagnostics,
|
|
233
255
|
removeDirectoryRule: () => removeDirectoryRule,
|
|
@@ -247,6 +269,7 @@ __export(index_exports, {
|
|
|
247
269
|
runFrontDoorSupervisor: () => runFrontDoorSupervisor,
|
|
248
270
|
runLauncher: () => runLauncher,
|
|
249
271
|
runSupervisor: () => runSupervisor,
|
|
272
|
+
sendRcKeepAlive: () => sendRcKeepAlive,
|
|
250
273
|
servedByPipeline: () => servedByPipeline,
|
|
251
274
|
setAllowAmbientCredential: () => setAllowAmbientCredential,
|
|
252
275
|
setDefaultConfigProfile: () => setDefaultConfigProfile,
|
|
@@ -262,6 +285,8 @@ __export(index_exports, {
|
|
|
262
285
|
snapshotPath: () => snapshotPath,
|
|
263
286
|
spawnClaude: () => spawnClaude,
|
|
264
287
|
startConnectServer: () => startConnectServer,
|
|
288
|
+
submitRcSessionMcpOAuthCallbackUrl: () => submitRcSessionMcpOAuthCallbackUrl,
|
|
289
|
+
suggestRcSessionFiles: () => suggestRcSessionFiles,
|
|
265
290
|
topLevelNames: () => topLevelNames,
|
|
266
291
|
updateDirectoryRule: () => updateDirectoryRule,
|
|
267
292
|
updateProvider: () => updateProvider,
|
|
@@ -3902,6 +3927,8 @@ function rcObserverAsPassthrough(observer) {
|
|
|
3902
3927
|
}
|
|
3903
3928
|
};
|
|
3904
3929
|
}
|
|
3930
|
+
|
|
3931
|
+
// src/frontdoor/rcWrites.ts
|
|
3905
3932
|
function buildRcUserMessagePayload(uuid, sessionId, text) {
|
|
3906
3933
|
return {
|
|
3907
3934
|
type: "user",
|
|
@@ -4002,14 +4029,55 @@ var RC_PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions", "plan"
|
|
|
4002
4029
|
function isRcPermissionMode(value) {
|
|
4003
4030
|
return RC_PERMISSION_MODES.some((mode) => mode === value);
|
|
4004
4031
|
}
|
|
4032
|
+
function buildRcControlRequestPayload(requestId, request4) {
|
|
4033
|
+
return { type: "control_request", request_id: requestId, request: request4 };
|
|
4034
|
+
}
|
|
4005
4035
|
function buildRcInterruptPayload(requestId) {
|
|
4006
|
-
return
|
|
4036
|
+
return buildRcControlRequestPayload(requestId, { subtype: "interrupt" });
|
|
4007
4037
|
}
|
|
4008
4038
|
function buildRcSetModelPayload(requestId, model) {
|
|
4009
|
-
return
|
|
4039
|
+
return buildRcControlRequestPayload(requestId, { subtype: "set_model", model });
|
|
4010
4040
|
}
|
|
4011
4041
|
function buildRcSetPermissionModePayload(requestId, mode) {
|
|
4012
|
-
return
|
|
4042
|
+
return buildRcControlRequestPayload(requestId, { subtype: "set_permission_mode", mode });
|
|
4043
|
+
}
|
|
4044
|
+
function buildRcEndSessionPayload(requestId, reason) {
|
|
4045
|
+
return buildRcControlRequestPayload(requestId, { subtype: "end_session", ...reason === void 0 ? {} : { reason } });
|
|
4046
|
+
}
|
|
4047
|
+
function buildRcGetUsagePayload(requestId, skipBehaviors) {
|
|
4048
|
+
return buildRcControlRequestPayload(requestId, { subtype: "get_usage", ...skipBehaviors === true ? { skip_behaviors: true } : {} });
|
|
4049
|
+
}
|
|
4050
|
+
var RC_CONTEXT_USAGE_DETAILS = ["summary", "full"];
|
|
4051
|
+
function isRcContextUsageDetail(value) {
|
|
4052
|
+
return RC_CONTEXT_USAGE_DETAILS.some((detail) => detail === value);
|
|
4053
|
+
}
|
|
4054
|
+
function buildRcGetContextUsagePayload(requestId, detail) {
|
|
4055
|
+
return buildRcControlRequestPayload(requestId, { subtype: "get_context_usage", ...detail === void 0 ? {} : { detail } });
|
|
4056
|
+
}
|
|
4057
|
+
var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
4058
|
+
function isRcReadFileEncoding(value) {
|
|
4059
|
+
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
4060
|
+
}
|
|
4061
|
+
function buildRcReadFilePayload(requestId, path32, options) {
|
|
4062
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path32, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
4063
|
+
}
|
|
4064
|
+
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
4065
|
+
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
4066
|
+
}
|
|
4067
|
+
function buildRcMcpStatusPayload(requestId) {
|
|
4068
|
+
return buildRcControlRequestPayload(requestId, { subtype: "mcp_status" });
|
|
4069
|
+
}
|
|
4070
|
+
function buildRcMcpReconnectPayload(requestId, serverName) {
|
|
4071
|
+
return buildRcControlRequestPayload(requestId, { subtype: "mcp_reconnect", serverName });
|
|
4072
|
+
}
|
|
4073
|
+
function buildRcMcpAuthenticatePayload(requestId, serverName, redirectUri) {
|
|
4074
|
+
return buildRcControlRequestPayload(requestId, { subtype: "mcp_authenticate", serverName, redirectUri });
|
|
4075
|
+
}
|
|
4076
|
+
function buildRcMcpOAuthCallbackUrlPayload(requestId, serverName, callbackUrl) {
|
|
4077
|
+
return buildRcControlRequestPayload(requestId, { subtype: "mcp_oauth_callback_url", serverName, callbackUrl });
|
|
4078
|
+
}
|
|
4079
|
+
function buildRcKeepAlivePayload() {
|
|
4080
|
+
return { type: "keep_alive" };
|
|
4013
4081
|
}
|
|
4014
4082
|
async function answerRcControlRequest(deps, sessionId, requestId, decision) {
|
|
4015
4083
|
const credential = deps.credentialOf(sessionId);
|
|
@@ -4036,7 +4104,7 @@ async function answerRcControlRequest(deps, sessionId, requestId, decision) {
|
|
|
4036
4104
|
}
|
|
4037
4105
|
return result;
|
|
4038
4106
|
}
|
|
4039
|
-
async function
|
|
4107
|
+
async function deliverRcClientPayload(deps, sessionId, payload, action) {
|
|
4040
4108
|
const credential = deps.credentialOf(sessionId);
|
|
4041
4109
|
if (credential === void 0) {
|
|
4042
4110
|
return { ok: false, message: rcSessionNotObservedMessage(sessionId) };
|
|
@@ -4044,12 +4112,12 @@ async function interruptRcSession(deps, sessionId) {
|
|
|
4044
4112
|
if (credential.authorization === void 0) {
|
|
4045
4113
|
return noOAuthCredentialResult(sessionId);
|
|
4046
4114
|
}
|
|
4047
|
-
const body = JSON.stringify(buildRcEventWriteBody(
|
|
4115
|
+
const body = JSON.stringify(buildRcEventWriteBody(payload));
|
|
4048
4116
|
let answer;
|
|
4049
4117
|
try {
|
|
4050
4118
|
answer = await deps.dial.writeEvents(sessionId, rcWriteHeaders(credential), body);
|
|
4051
4119
|
} catch (error) {
|
|
4052
|
-
return { ok: false, message: `the door could not reach the API host to
|
|
4120
|
+
return { ok: false, message: `the door could not reach the API host to ${action}: ${error instanceof Error ? error.message : String(error)}` };
|
|
4053
4121
|
}
|
|
4054
4122
|
const result = rcEventWriteResultFromAnswer(answer);
|
|
4055
4123
|
if (result.ok) {
|
|
@@ -4057,50 +4125,89 @@ async function interruptRcSession(deps, sessionId) {
|
|
|
4057
4125
|
}
|
|
4058
4126
|
return result;
|
|
4059
4127
|
}
|
|
4128
|
+
async function interruptRcSession(deps, sessionId) {
|
|
4129
|
+
const requestId = deps.newUuid();
|
|
4130
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcInterruptPayload(requestId), `interrupt session ${sessionId}`);
|
|
4131
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4132
|
+
}
|
|
4060
4133
|
async function setRcSessionModel(deps, sessionId, model) {
|
|
4061
4134
|
if (model === "") {
|
|
4062
4135
|
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" };
|
|
4063
4136
|
}
|
|
4064
|
-
const
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4137
|
+
const requestId = deps.newUuid();
|
|
4138
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcSetModelPayload(requestId, model), `set the model on session ${sessionId}`);
|
|
4139
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4140
|
+
}
|
|
4141
|
+
async function setRcSessionPermissionMode(deps, sessionId, mode) {
|
|
4142
|
+
const requestId = deps.newUuid();
|
|
4143
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcSetPermissionModePayload(requestId, mode), `set the permission mode on session ${sessionId}`);
|
|
4144
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4145
|
+
}
|
|
4146
|
+
async function endRcSession(deps, sessionId, reason) {
|
|
4147
|
+
if (reason === "") {
|
|
4148
|
+
return { ok: false, message: "an end-session write needs either no reason or a non-empty one: the worker reads an absent reason as its own unspecified form, and an empty string is neither" };
|
|
4070
4149
|
}
|
|
4071
|
-
const
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4150
|
+
const requestId = deps.newUuid();
|
|
4151
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcEndSessionPayload(requestId, reason), `end session ${sessionId}`);
|
|
4152
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4153
|
+
}
|
|
4154
|
+
async function getRcSessionUsage(deps, sessionId, skipBehaviors) {
|
|
4155
|
+
const requestId = deps.newUuid();
|
|
4156
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetUsagePayload(requestId, skipBehaviors), `request the usage of session ${sessionId}`);
|
|
4157
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4158
|
+
}
|
|
4159
|
+
async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
4160
|
+
const requestId = deps.newUuid();
|
|
4161
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
4162
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4163
|
+
}
|
|
4164
|
+
async function readRcSessionFile(deps, sessionId, path32, options) {
|
|
4165
|
+
if (path32 === "") {
|
|
4166
|
+
return { ok: false, message: "a read-file write needs a non-empty path: the SDK's own field names the file the worker resolves against the session's cwd, and an empty string names none" };
|
|
4077
4167
|
}
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
deps.noteSequenceNums(sessionId, result.sequenceNums);
|
|
4168
|
+
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
4169
|
+
return { ok: false, message: "a read-file write's max-bytes is a positive whole number of bytes: the SDK's own field caps the read, and a zero or negative cap reads nothing" };
|
|
4081
4170
|
}
|
|
4082
|
-
|
|
4171
|
+
const requestId = deps.newUuid();
|
|
4172
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path32, options), `read ${path32} from session ${sessionId}`);
|
|
4173
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4083
4174
|
}
|
|
4084
|
-
async function
|
|
4085
|
-
const
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4175
|
+
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
4176
|
+
const requestId = deps.newUuid();
|
|
4177
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcFileSuggestionsPayload(requestId, query), `request file suggestions from session ${sessionId}`);
|
|
4178
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4179
|
+
}
|
|
4180
|
+
async function getRcSessionMcpStatus(deps, sessionId) {
|
|
4181
|
+
const requestId = deps.newUuid();
|
|
4182
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcMcpStatusPayload(requestId), `request the MCP status of session ${sessionId}`);
|
|
4183
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4184
|
+
}
|
|
4185
|
+
async function reconnectRcSessionMcpServer(deps, sessionId, serverName) {
|
|
4186
|
+
if (serverName === "") {
|
|
4187
|
+
return { ok: false, message: "an mcp-reconnect write needs a non-empty server name: the SDK's own field names the server as mcp_status reports it, and an empty string names none" };
|
|
4091
4188
|
}
|
|
4092
|
-
const
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4189
|
+
const requestId = deps.newUuid();
|
|
4190
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcMcpReconnectPayload(requestId, serverName), `reconnect MCP server ${serverName} on session ${sessionId}`);
|
|
4191
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4192
|
+
}
|
|
4193
|
+
async function authenticateRcSessionMcpServer(deps, sessionId, serverName, redirectUri) {
|
|
4194
|
+
if (serverName === "" || redirectUri === "") {
|
|
4195
|
+
return { ok: false, message: "an mcp-authenticate write needs a non-empty server name and redirect URI: the CLI's own request names the server and where its OAuth flow redirects back to, and an empty string names neither" };
|
|
4098
4196
|
}
|
|
4099
|
-
const
|
|
4100
|
-
|
|
4101
|
-
|
|
4197
|
+
const requestId = deps.newUuid();
|
|
4198
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcMcpAuthenticatePayload(requestId, serverName, redirectUri), `authenticate MCP server ${serverName} on session ${sessionId}`);
|
|
4199
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4200
|
+
}
|
|
4201
|
+
async function submitRcSessionMcpOAuthCallbackUrl(deps, sessionId, serverName, callbackUrl) {
|
|
4202
|
+
if (serverName === "" || callbackUrl === "") {
|
|
4203
|
+
return { ok: false, message: "an mcp-oauth-callback-url write needs a non-empty server name and callback URL: the CLI's own request names the server and the URL its OAuth flow landed on, and an empty string names neither" };
|
|
4102
4204
|
}
|
|
4103
|
-
|
|
4205
|
+
const requestId = deps.newUuid();
|
|
4206
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcMcpOAuthCallbackUrlPayload(requestId, serverName, callbackUrl), `hand MCP server ${serverName}'s OAuth callback to session ${sessionId}`);
|
|
4207
|
+
return result.ok ? { ...result, requestId } : result;
|
|
4208
|
+
}
|
|
4209
|
+
async function sendRcKeepAlive(deps, sessionId) {
|
|
4210
|
+
return await deliverRcClientPayload(deps, sessionId, buildRcKeepAlivePayload(), `keep session ${sessionId} alive`);
|
|
4104
4211
|
}
|
|
4105
4212
|
|
|
4106
4213
|
// src/frontdoor/rcControl.ts
|
|
@@ -4112,6 +4219,25 @@ function answerJson(response, status, body) {
|
|
|
4112
4219
|
response.writeHead(status, { "content-type": "application/json", "content-length": String(Buffer.byteLength(text, "utf8")) });
|
|
4113
4220
|
response.end(text);
|
|
4114
4221
|
}
|
|
4222
|
+
function isJsonObject(value) {
|
|
4223
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4224
|
+
}
|
|
4225
|
+
function bodyString(body, field) {
|
|
4226
|
+
const value = body[field];
|
|
4227
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
4228
|
+
}
|
|
4229
|
+
function bodyStringAllowingEmpty(body, field) {
|
|
4230
|
+
const value = body[field];
|
|
4231
|
+
return typeof value === "string" ? value : void 0;
|
|
4232
|
+
}
|
|
4233
|
+
function bodyBoolean(body, field) {
|
|
4234
|
+
const value = body[field];
|
|
4235
|
+
return typeof value === "boolean" ? value : void 0;
|
|
4236
|
+
}
|
|
4237
|
+
function bodyPositiveInteger(body, field) {
|
|
4238
|
+
const value = body[field];
|
|
4239
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : void 0;
|
|
4240
|
+
}
|
|
4115
4241
|
async function readBody(request4) {
|
|
4116
4242
|
return await new Promise((resolve, reject) => {
|
|
4117
4243
|
const chunks = [];
|
|
@@ -4139,9 +4265,127 @@ function createRcControlHandler(deps) {
|
|
|
4139
4265
|
const pendingPath = `${CONTROL_PATH_PREFIX}/pending`;
|
|
4140
4266
|
const injectPath = `${CONTROL_PATH_PREFIX}/inject`;
|
|
4141
4267
|
const answerPath = `${CONTROL_PATH_PREFIX}/answer`;
|
|
4142
|
-
const
|
|
4143
|
-
|
|
4144
|
-
|
|
4268
|
+
const controlWrites = [
|
|
4269
|
+
{
|
|
4270
|
+
name: "interrupt",
|
|
4271
|
+
path: "interrupt",
|
|
4272
|
+
read: (body) => {
|
|
4273
|
+
const session = bodyString(body, "session");
|
|
4274
|
+
return session === void 0 ? { error: "the interrupt body must be JSON naming a non-empty session id" } : { session, run: async () => await deps.interrupt(session) };
|
|
4275
|
+
}
|
|
4276
|
+
},
|
|
4277
|
+
{
|
|
4278
|
+
name: "set-model",
|
|
4279
|
+
path: "set-model",
|
|
4280
|
+
read: (body) => {
|
|
4281
|
+
const session = bodyString(body, "session");
|
|
4282
|
+
const model = bodyString(body, "model");
|
|
4283
|
+
return session === void 0 || model === void 0 ? { error: "the set-model body must be JSON naming a non-empty session id and model id" } : { session, run: async () => await deps.setModel(session, model) };
|
|
4284
|
+
}
|
|
4285
|
+
},
|
|
4286
|
+
{
|
|
4287
|
+
name: "set-permission-mode",
|
|
4288
|
+
path: "set-permission-mode",
|
|
4289
|
+
read: (body) => {
|
|
4290
|
+
const session = bodyString(body, "session");
|
|
4291
|
+
const mode = body.mode;
|
|
4292
|
+
return session === void 0 || !isRcPermissionMode(mode) ? { 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})` } : { session, run: async () => await deps.setPermissionMode(session, mode) };
|
|
4293
|
+
}
|
|
4294
|
+
},
|
|
4295
|
+
{
|
|
4296
|
+
name: "end-session",
|
|
4297
|
+
path: "end-session",
|
|
4298
|
+
read: (body) => {
|
|
4299
|
+
const session = bodyString(body, "session");
|
|
4300
|
+
const reason = "reason" in body ? bodyString(body, "reason") : void 0;
|
|
4301
|
+
return session === void 0 || "reason" in body && reason === void 0 ? { error: "the end-session body must be JSON naming a non-empty session id, and a reason only as a non-empty string or absent" } : { session, run: async () => await deps.endSession(session, reason) };
|
|
4302
|
+
}
|
|
4303
|
+
},
|
|
4304
|
+
{
|
|
4305
|
+
name: "get-usage",
|
|
4306
|
+
path: "get-usage",
|
|
4307
|
+
read: (body) => {
|
|
4308
|
+
const session = bodyString(body, "session");
|
|
4309
|
+
const skipBehaviors = "skipBehaviors" in body ? bodyBoolean(body, "skipBehaviors") : void 0;
|
|
4310
|
+
return session === void 0 || "skipBehaviors" in body && skipBehaviors === void 0 ? { error: "the get-usage body must be JSON naming a non-empty session id, and skipBehaviors only as a boolean or absent" } : { session, run: async () => await deps.getUsage(session, skipBehaviors) };
|
|
4311
|
+
}
|
|
4312
|
+
},
|
|
4313
|
+
{
|
|
4314
|
+
name: "get-context-usage",
|
|
4315
|
+
path: "get-context-usage",
|
|
4316
|
+
read: (body) => {
|
|
4317
|
+
const session = bodyString(body, "session");
|
|
4318
|
+
const detail = "detail" in body && isRcContextUsageDetail(body.detail) ? body.detail : void 0;
|
|
4319
|
+
return session === void 0 || "detail" in body && detail === void 0 ? { error: `the get-context-usage body must be JSON naming a non-empty session id, and a detail level the SDK's own type permits (${RC_CONTEXT_USAGE_DETAILS.join(", ")}) or none` } : { session, run: async () => await deps.getContextUsage(session, detail) };
|
|
4320
|
+
}
|
|
4321
|
+
},
|
|
4322
|
+
{
|
|
4323
|
+
name: "read-file",
|
|
4324
|
+
path: "read-file",
|
|
4325
|
+
read: (body) => {
|
|
4326
|
+
const session = bodyString(body, "session");
|
|
4327
|
+
const path32 = bodyString(body, "path");
|
|
4328
|
+
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
4329
|
+
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
4330
|
+
const refused2 = session === void 0 || path32 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
4331
|
+
return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path32, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
4332
|
+
}
|
|
4333
|
+
},
|
|
4334
|
+
{
|
|
4335
|
+
name: "file-suggestions",
|
|
4336
|
+
path: "file-suggestions",
|
|
4337
|
+
read: (body) => {
|
|
4338
|
+
const session = bodyString(body, "session");
|
|
4339
|
+
const query = bodyStringAllowingEmpty(body, "query");
|
|
4340
|
+
return session === void 0 || query === void 0 ? { error: "the file-suggestions body must be JSON naming a non-empty session id and a query string, which may be empty" } : { session, run: async () => await deps.fileSuggestions(session, query) };
|
|
4341
|
+
}
|
|
4342
|
+
},
|
|
4343
|
+
{
|
|
4344
|
+
name: "keep-alive",
|
|
4345
|
+
path: "keep-alive",
|
|
4346
|
+
read: (body) => {
|
|
4347
|
+
const session = bodyString(body, "session");
|
|
4348
|
+
return session === void 0 ? { error: "the keep-alive body must be JSON naming a non-empty session id" } : { session, run: async () => await deps.keepAlive(session) };
|
|
4349
|
+
}
|
|
4350
|
+
},
|
|
4351
|
+
{
|
|
4352
|
+
name: "mcp-status",
|
|
4353
|
+
path: "mcp-status",
|
|
4354
|
+
read: (body) => {
|
|
4355
|
+
const session = bodyString(body, "session");
|
|
4356
|
+
return session === void 0 ? { error: "the mcp-status body must be JSON naming a non-empty session id" } : { session, run: async () => await deps.mcpStatus(session) };
|
|
4357
|
+
}
|
|
4358
|
+
},
|
|
4359
|
+
{
|
|
4360
|
+
name: "mcp-reconnect",
|
|
4361
|
+
path: "mcp-reconnect",
|
|
4362
|
+
read: (body) => {
|
|
4363
|
+
const session = bodyString(body, "session");
|
|
4364
|
+
const serverName = bodyString(body, "serverName");
|
|
4365
|
+
return session === void 0 || serverName === void 0 ? { error: "the mcp-reconnect body must be JSON naming a non-empty session id and server name" } : { session, run: async () => await deps.mcpReconnect(session, serverName) };
|
|
4366
|
+
}
|
|
4367
|
+
},
|
|
4368
|
+
{
|
|
4369
|
+
name: "mcp-authenticate",
|
|
4370
|
+
path: "mcp-authenticate",
|
|
4371
|
+
read: (body) => {
|
|
4372
|
+
const session = bodyString(body, "session");
|
|
4373
|
+
const serverName = bodyString(body, "serverName");
|
|
4374
|
+
const redirectUri = bodyString(body, "redirectUri");
|
|
4375
|
+
return session === void 0 || serverName === void 0 || redirectUri === void 0 ? { error: "the mcp-authenticate body must be JSON naming a non-empty session id, server name, and redirect URI" } : { session, run: async () => await deps.mcpAuthenticate(session, serverName, redirectUri) };
|
|
4376
|
+
}
|
|
4377
|
+
},
|
|
4378
|
+
{
|
|
4379
|
+
name: "mcp-oauth-callback-url",
|
|
4380
|
+
path: "mcp-oauth-callback-url",
|
|
4381
|
+
read: (body) => {
|
|
4382
|
+
const session = bodyString(body, "session");
|
|
4383
|
+
const serverName = bodyString(body, "serverName");
|
|
4384
|
+
const callbackUrl = bodyString(body, "callbackUrl");
|
|
4385
|
+
return session === void 0 || serverName === void 0 || callbackUrl === void 0 ? { error: "the mcp-oauth-callback-url body must be JSON naming a non-empty session id, server name, and callback URL" } : { session, run: async () => await deps.mcpOAuthCallbackUrl(session, serverName, callbackUrl) };
|
|
4386
|
+
}
|
|
4387
|
+
}
|
|
4388
|
+
];
|
|
4145
4389
|
return (request4, response) => {
|
|
4146
4390
|
const presented = request4.headers.authorization;
|
|
4147
4391
|
const bearerPrefix = "bearer ".length;
|
|
@@ -4226,73 +4470,33 @@ function createRcControlHandler(deps) {
|
|
|
4226
4470
|
answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
|
|
4227
4471
|
return;
|
|
4228
4472
|
}
|
|
4229
|
-
|
|
4230
|
-
if (
|
|
4231
|
-
|
|
4232
|
-
return;
|
|
4233
|
-
}
|
|
4234
|
-
let parsed;
|
|
4235
|
-
try {
|
|
4236
|
-
parsed = JSON.parse(await readBody(request4));
|
|
4237
|
-
} catch {
|
|
4238
|
-
answerJson(response, HTTP_STATUS.badRequest, { error: "the interrupt body is not readable JSON within the control body cap" });
|
|
4239
|
-
return;
|
|
4240
|
-
}
|
|
4241
|
-
if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || typeof parsed.session !== "string" || parsed.session === "") {
|
|
4242
|
-
answerJson(response, HTTP_STATUS.badRequest, { error: "the interrupt body must be JSON naming a non-empty session id" });
|
|
4243
|
-
return;
|
|
4244
|
-
}
|
|
4245
|
-
const result = await deps.interrupt(parsed.session);
|
|
4246
|
-
if (result.ok) {
|
|
4247
|
-
answerJson(response, HTTP_STATUS.ok, { session: parsed.session, sequenceNums: result.sequenceNums });
|
|
4248
|
-
return;
|
|
4473
|
+
for (const route of controlWrites) {
|
|
4474
|
+
if (url.pathname !== `${CONTROL_PATH_PREFIX}/${route.path}`) {
|
|
4475
|
+
continue;
|
|
4249
4476
|
}
|
|
4250
|
-
answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
|
|
4251
|
-
return;
|
|
4252
|
-
}
|
|
4253
|
-
if (url.pathname === setModelPath) {
|
|
4254
4477
|
if (request4.method !== "POST") {
|
|
4255
|
-
answerJson(response, HTTP_STATUS.methodNotAllowed, { error:
|
|
4478
|
+
answerJson(response, HTTP_STATUS.methodNotAllowed, { error: `the ${route.name} operation is a POST` });
|
|
4256
4479
|
return;
|
|
4257
4480
|
}
|
|
4258
4481
|
let parsed;
|
|
4259
4482
|
try {
|
|
4260
4483
|
parsed = JSON.parse(await readBody(request4));
|
|
4261
4484
|
} catch {
|
|
4262
|
-
answerJson(response, HTTP_STATUS.badRequest, { error:
|
|
4485
|
+
answerJson(response, HTTP_STATUS.badRequest, { error: `the ${route.name} body is not readable JSON within the control body cap` });
|
|
4263
4486
|
return;
|
|
4264
4487
|
}
|
|
4265
|
-
if (
|
|
4266
|
-
answerJson(response, HTTP_STATUS.badRequest, { error:
|
|
4488
|
+
if (!isJsonObject(parsed)) {
|
|
4489
|
+
answerJson(response, HTTP_STATUS.badRequest, { error: `the ${route.name} body must be a JSON object` });
|
|
4267
4490
|
return;
|
|
4268
4491
|
}
|
|
4269
|
-
const
|
|
4270
|
-
if (
|
|
4271
|
-
answerJson(response, HTTP_STATUS.
|
|
4492
|
+
const read = route.read(parsed);
|
|
4493
|
+
if ("error" in read) {
|
|
4494
|
+
answerJson(response, HTTP_STATUS.badRequest, { error: read.error });
|
|
4272
4495
|
return;
|
|
4273
4496
|
}
|
|
4274
|
-
|
|
4275
|
-
return;
|
|
4276
|
-
}
|
|
4277
|
-
if (url.pathname === setPermissionModePath) {
|
|
4278
|
-
if (request4.method !== "POST") {
|
|
4279
|
-
answerJson(response, HTTP_STATUS.methodNotAllowed, { error: "the set-permission-mode operation is a POST" });
|
|
4280
|
-
return;
|
|
4281
|
-
}
|
|
4282
|
-
let parsed;
|
|
4283
|
-
try {
|
|
4284
|
-
parsed = JSON.parse(await readBody(request4));
|
|
4285
|
-
} catch {
|
|
4286
|
-
answerJson(response, HTTP_STATUS.badRequest, { error: "the set-permission-mode body is not readable JSON within the control body cap" });
|
|
4287
|
-
return;
|
|
4288
|
-
}
|
|
4289
|
-
if (typeof parsed !== "object" || parsed === null || !("session" in parsed) || !("mode" in parsed) || typeof parsed.session !== "string" || parsed.session === "" || !isRcPermissionMode(parsed.mode)) {
|
|
4290
|
-
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})` });
|
|
4291
|
-
return;
|
|
4292
|
-
}
|
|
4293
|
-
const result = await deps.setPermissionMode(parsed.session, parsed.mode);
|
|
4497
|
+
const result = await read.run();
|
|
4294
4498
|
if (result.ok) {
|
|
4295
|
-
answerJson(response, HTTP_STATUS.ok, { session:
|
|
4499
|
+
answerJson(response, HTTP_STATUS.ok, { session: read.session, ...result.requestId === void 0 ? {} : { request: result.requestId }, sequenceNums: result.sequenceNums });
|
|
4296
4500
|
return;
|
|
4297
4501
|
}
|
|
4298
4502
|
answerJson(response, HTTP_STATUS.badGateway, { error: result.message });
|
|
@@ -4410,6 +4614,19 @@ function sequenceNumsOfBody(body) {
|
|
|
4410
4614
|
}
|
|
4411
4615
|
return sequenceNums;
|
|
4412
4616
|
}
|
|
4617
|
+
function requestIdOfBody(body) {
|
|
4618
|
+
let parsed;
|
|
4619
|
+
try {
|
|
4620
|
+
parsed = JSON.parse(body);
|
|
4621
|
+
} catch {
|
|
4622
|
+
return void 0;
|
|
4623
|
+
}
|
|
4624
|
+
if (typeof parsed !== "object" || parsed === null || !("request" in parsed)) {
|
|
4625
|
+
return void 0;
|
|
4626
|
+
}
|
|
4627
|
+
const value = parsed.request;
|
|
4628
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
4629
|
+
}
|
|
4413
4630
|
function frontDoorRcControl(transport, token) {
|
|
4414
4631
|
const headers = { authorization: `Bearer ${token}` };
|
|
4415
4632
|
const listAnswerOf = async (path32, what) => {
|
|
@@ -4498,7 +4715,8 @@ function frontDoorRcControl(transport, token) {
|
|
|
4498
4715
|
if (sequenceNums === void 0) {
|
|
4499
4716
|
return { ok: false, message: `the door accepted the event but its answer named no sequence numbers: ${answer.body}` };
|
|
4500
4717
|
}
|
|
4501
|
-
|
|
4718
|
+
const requestId = requestIdOfBody(answer.body);
|
|
4719
|
+
return requestId === void 0 ? { ok: true, sequenceNums } : { ok: true, sequenceNums, requestId };
|
|
4502
4720
|
}
|
|
4503
4721
|
return { ok: false, message: describeFailure(answer.status, controlErrorOf(answer.body) ?? answer.body) };
|
|
4504
4722
|
};
|
|
@@ -4515,7 +4733,21 @@ function frontDoorRcControl(transport, token) {
|
|
|
4515
4733
|
),
|
|
4516
4734
|
interruptSession: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/interrupt`, JSON.stringify({ session: sessionId }), (status, message) => `interrupting ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4517
4735
|
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}`),
|
|
4518
|
-
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}`)
|
|
4736
|
+
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}`),
|
|
4737
|
+
endSession: async (sessionId, reason) => await writeOf(`${CONTROL_PATH_PREFIX}/end-session`, JSON.stringify({ session: sessionId, ...reason === void 0 ? {} : { reason } }), (status, message) => `ending ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4738
|
+
getUsage: async (sessionId, skipBehaviors) => await writeOf(`${CONTROL_PATH_PREFIX}/get-usage`, JSON.stringify({ session: sessionId, ...skipBehaviors === void 0 ? {} : { skipBehaviors } }), (status, message) => `requesting the usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4739
|
+
getContextUsage: async (sessionId, detail) => await writeOf(`${CONTROL_PATH_PREFIX}/get-context-usage`, JSON.stringify({ session: sessionId, ...detail === void 0 ? {} : { detail } }), (status, message) => `requesting the context usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4740
|
+
readFile: async (sessionId, path32, options) => await writeOf(
|
|
4741
|
+
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
4742
|
+
JSON.stringify({ session: sessionId, path: path32, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
4743
|
+
(status, message) => `reading ${path32} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
4744
|
+
),
|
|
4745
|
+
fileSuggestions: async (sessionId, query) => await writeOf(`${CONTROL_PATH_PREFIX}/file-suggestions`, JSON.stringify({ session: sessionId, query }), (status, message) => `requesting file suggestions from ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4746
|
+
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
4747
|
+
mcpStatus: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-status`, JSON.stringify({ session: sessionId }), (status, message) => `requesting the MCP status of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4748
|
+
mcpReconnect: async (sessionId, serverName) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-reconnect`, JSON.stringify({ session: sessionId, serverName }), (status, message) => `reconnecting MCP server ${serverName} on ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4749
|
+
mcpAuthenticate: async (sessionId, serverName, redirectUri) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-authenticate`, JSON.stringify({ session: sessionId, serverName, redirectUri }), (status, message) => `authenticating MCP server ${serverName} on ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
4750
|
+
mcpOAuthCallbackUrl: async (sessionId, serverName, callbackUrl) => await writeOf(`${CONTROL_PATH_PREFIX}/mcp-oauth-callback-url`, JSON.stringify({ session: sessionId, serverName, callbackUrl }), (status, message) => `handing MCP server ${serverName}'s OAuth callback to ${sessionId} failed (HTTP ${String(status)}): ${message}`)
|
|
4519
4751
|
};
|
|
4520
4752
|
}
|
|
4521
4753
|
|
|
@@ -5137,6 +5369,48 @@ var RcSetPermissionModeInputSchema = import_zod4.z.strictObject({
|
|
|
5137
5369
|
session: import_zod4.z.string().min(1),
|
|
5138
5370
|
mode: RcPermissionModeSchema
|
|
5139
5371
|
});
|
|
5372
|
+
var RcEndSessionInputSchema = import_zod4.z.strictObject({
|
|
5373
|
+
session: import_zod4.z.string().min(1),
|
|
5374
|
+
reason: import_zod4.z.string().min(1).optional()
|
|
5375
|
+
});
|
|
5376
|
+
var RcGetUsageInputSchema = import_zod4.z.strictObject({
|
|
5377
|
+
session: import_zod4.z.string().min(1),
|
|
5378
|
+
skipBehaviors: import_zod4.z.boolean().optional()
|
|
5379
|
+
});
|
|
5380
|
+
var RcGetContextUsageInputSchema = import_zod4.z.strictObject({
|
|
5381
|
+
session: import_zod4.z.string().min(1),
|
|
5382
|
+
detail: import_zod4.z.enum(RC_CONTEXT_USAGE_DETAILS).optional()
|
|
5383
|
+
});
|
|
5384
|
+
var RcReadFileInputSchema = import_zod4.z.strictObject({
|
|
5385
|
+
session: import_zod4.z.string().min(1),
|
|
5386
|
+
path: import_zod4.z.string().min(1),
|
|
5387
|
+
maxBytes: import_zod4.z.number().int().positive().optional(),
|
|
5388
|
+
encoding: import_zod4.z.enum(RC_READ_FILE_ENCODINGS).optional()
|
|
5389
|
+
});
|
|
5390
|
+
var RcFileSuggestionsInputSchema = import_zod4.z.strictObject({
|
|
5391
|
+
session: import_zod4.z.string().min(1),
|
|
5392
|
+
query: import_zod4.z.string()
|
|
5393
|
+
});
|
|
5394
|
+
var RcKeepAliveInputSchema = import_zod4.z.strictObject({
|
|
5395
|
+
session: import_zod4.z.string().min(1)
|
|
5396
|
+
});
|
|
5397
|
+
var RcMcpStatusInputSchema = import_zod4.z.strictObject({
|
|
5398
|
+
session: import_zod4.z.string().min(1)
|
|
5399
|
+
});
|
|
5400
|
+
var RcMcpReconnectInputSchema = import_zod4.z.strictObject({
|
|
5401
|
+
session: import_zod4.z.string().min(1),
|
|
5402
|
+
serverName: import_zod4.z.string().min(1)
|
|
5403
|
+
});
|
|
5404
|
+
var RcMcpAuthenticateInputSchema = import_zod4.z.strictObject({
|
|
5405
|
+
session: import_zod4.z.string().min(1),
|
|
5406
|
+
serverName: import_zod4.z.string().min(1),
|
|
5407
|
+
redirectUri: import_zod4.z.string().min(1)
|
|
5408
|
+
});
|
|
5409
|
+
var RcMcpOAuthCallbackUrlInputSchema = import_zod4.z.strictObject({
|
|
5410
|
+
session: import_zod4.z.string().min(1),
|
|
5411
|
+
serverName: import_zod4.z.string().min(1),
|
|
5412
|
+
callbackUrl: import_zod4.z.string().min(1)
|
|
5413
|
+
});
|
|
5140
5414
|
var RcListOutputSchema = import_zod4.z.strictObject({ sessions: import_zod4.z.readonly(import_zod4.z.array(RcSessionSummarySchema)) });
|
|
5141
5415
|
var RcStatusOutputSchema = import_zod4.z.strictObject({ statuses: import_zod4.z.readonly(import_zod4.z.array(RcSessionStatusSchema)) });
|
|
5142
5416
|
var RcPendingOutputSchema = import_zod4.z.strictObject({ pending: import_zod4.z.readonly(import_zod4.z.array(RcPendingRequestSummarySchema)) });
|
|
@@ -5144,6 +5418,11 @@ var RcWriteOutputSchema = import_zod4.z.strictObject({
|
|
|
5144
5418
|
session: import_zod4.z.string(),
|
|
5145
5419
|
sequenceNums: import_zod4.z.readonly(import_zod4.z.array(import_zod4.z.number()))
|
|
5146
5420
|
});
|
|
5421
|
+
var RcControlWriteOutputSchema = import_zod4.z.strictObject({
|
|
5422
|
+
session: import_zod4.z.string(),
|
|
5423
|
+
request: import_zod4.z.string(),
|
|
5424
|
+
sequenceNums: import_zod4.z.readonly(import_zod4.z.array(import_zod4.z.number()))
|
|
5425
|
+
});
|
|
5147
5426
|
var RcAnswerOutputSchema = import_zod4.z.strictObject({
|
|
5148
5427
|
session: import_zod4.z.string(),
|
|
5149
5428
|
request: import_zod4.z.string(),
|
|
@@ -5172,6 +5451,15 @@ function createRcApiRouter(deps) {
|
|
|
5172
5451
|
}
|
|
5173
5452
|
return result.sequenceNums;
|
|
5174
5453
|
};
|
|
5454
|
+
const deliveredControl = (sessionId, result) => {
|
|
5455
|
+
if (!result.ok) {
|
|
5456
|
+
throw new import_client.ORPCError("BAD_GATEWAY", { message: result.message });
|
|
5457
|
+
}
|
|
5458
|
+
if (result.requestId === void 0) {
|
|
5459
|
+
throw new import_client.ORPCError("INTERNAL_SERVER_ERROR", { message: "the control request was delivered but the door cannot name the request id it minted, so the worker's answer cannot be matched" });
|
|
5460
|
+
}
|
|
5461
|
+
return { request: result.requestId, sequenceNums: result.sequenceNums };
|
|
5462
|
+
};
|
|
5175
5463
|
return {
|
|
5176
5464
|
rc: {
|
|
5177
5465
|
list: authed.output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
|
|
@@ -5194,9 +5482,19 @@ function createRcApiRouter(deps) {
|
|
|
5194
5482
|
const decision = { approve: input.approve, message: input.approve || input.text === void 0 ? void 0 : input.text };
|
|
5195
5483
|
return { session: input.session, request: input.request, sequenceNums: delivered(input.session, await deps.answer(input.session, input.request, decision)) };
|
|
5196
5484
|
}),
|
|
5197
|
-
interrupt: authed.input(RcInterruptInputSchema).output(
|
|
5198
|
-
setModel: authed.input(RcSetModelInputSchema).output(
|
|
5199
|
-
setPermissionMode: authed.input(RcSetPermissionModeInputSchema).output(
|
|
5485
|
+
interrupt: authed.input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
|
|
5486
|
+
setModel: authed.input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
|
|
5487
|
+
setPermissionMode: authed.input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
|
|
5488
|
+
endSession: authed.input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
|
|
5489
|
+
getUsage: authed.input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
|
|
5490
|
+
getContextUsage: authed.input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
|
|
5491
|
+
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 } })) })),
|
|
5492
|
+
fileSuggestions: authed.input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
|
|
5493
|
+
keepAlive: authed.input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
|
|
5494
|
+
mcpStatus: authed.input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
|
|
5495
|
+
mcpReconnect: authed.input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
|
|
5496
|
+
mcpAuthenticate: authed.input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
|
|
5497
|
+
mcpOAuthCallbackUrl: authed.input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
|
|
5200
5498
|
subscribe: authed.input(RcSessionQuerySchema).output((0, import_server2.eventIterator)(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
|
|
5201
5499
|
const queue = [];
|
|
5202
5500
|
let wake;
|
|
@@ -11466,7 +11764,7 @@ var import_node_path30 = __toESM(require("node:path"), 1);
|
|
|
11466
11764
|
// package.json
|
|
11467
11765
|
var package_default = {
|
|
11468
11766
|
name: "agent-shim",
|
|
11469
|
-
version: "8.
|
|
11767
|
+
version: "8.24.0",
|
|
11470
11768
|
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.",
|
|
11471
11769
|
license: "MIT",
|
|
11472
11770
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -12709,10 +13007,12 @@ function prepareClaudeLaunch(options) {
|
|
|
12709
13007
|
ProviderKindMismatchError,
|
|
12710
13008
|
ProviderNotFoundError,
|
|
12711
13009
|
ProviderSchema,
|
|
13010
|
+
RC_CONTEXT_USAGE_DETAILS,
|
|
12712
13011
|
RC_IDLE_EXPIRY_MS,
|
|
12713
13012
|
RC_ORPC_PATH_PREFIX,
|
|
12714
13013
|
RC_PENDING_DEADLINE_MS,
|
|
12715
13014
|
RC_PERMISSION_MODES,
|
|
13015
|
+
RC_READ_FILE_ENCODINGS,
|
|
12716
13016
|
RC_REQUEST_PARSE_CAP_BYTES,
|
|
12717
13017
|
RC_SELF_HOST_ENV,
|
|
12718
13018
|
RC_SELF_HOST_KEEPALIVE_MS,
|
|
@@ -12743,11 +13043,23 @@ function prepareClaudeLaunch(options) {
|
|
|
12743
13043
|
addPool,
|
|
12744
13044
|
addProvider,
|
|
12745
13045
|
answerRcControlRequest,
|
|
13046
|
+
authenticateRcSessionMcpServer,
|
|
12746
13047
|
buildEntryFacts,
|
|
12747
13048
|
buildLayoutPaths,
|
|
13049
|
+
buildRcControlRequestPayload,
|
|
12748
13050
|
buildRcControlResponsePayload,
|
|
13051
|
+
buildRcEndSessionPayload,
|
|
12749
13052
|
buildRcEventWriteBody,
|
|
13053
|
+
buildRcFileSuggestionsPayload,
|
|
13054
|
+
buildRcGetContextUsagePayload,
|
|
13055
|
+
buildRcGetUsagePayload,
|
|
12750
13056
|
buildRcInterruptPayload,
|
|
13057
|
+
buildRcKeepAlivePayload,
|
|
13058
|
+
buildRcMcpAuthenticatePayload,
|
|
13059
|
+
buildRcMcpOAuthCallbackUrlPayload,
|
|
13060
|
+
buildRcMcpReconnectPayload,
|
|
13061
|
+
buildRcMcpStatusPayload,
|
|
13062
|
+
buildRcReadFilePayload,
|
|
12751
13063
|
buildRcSetModelPayload,
|
|
12752
13064
|
buildRcSetPermissionModePayload,
|
|
12753
13065
|
buildRcUserMessagePayload,
|
|
@@ -12780,6 +13092,7 @@ function prepareClaudeLaunch(options) {
|
|
|
12780
13092
|
doorApiAuth,
|
|
12781
13093
|
doorApiNodeHandlerOf,
|
|
12782
13094
|
effectiveWindow,
|
|
13095
|
+
endRcSession,
|
|
12783
13096
|
ensureCa,
|
|
12784
13097
|
ensureFrontDoor,
|
|
12785
13098
|
ensureHeadroom,
|
|
@@ -12796,6 +13109,9 @@ function prepareClaudeLaunch(options) {
|
|
|
12796
13109
|
frontDoorRcApiClient,
|
|
12797
13110
|
frontDoorRcControl,
|
|
12798
13111
|
generateCa,
|
|
13112
|
+
getRcSessionContextUsage,
|
|
13113
|
+
getRcSessionMcpStatus,
|
|
13114
|
+
getRcSessionUsage,
|
|
12799
13115
|
headroomSocketTarget,
|
|
12800
13116
|
identityExists,
|
|
12801
13117
|
injectRcUserMessage,
|
|
@@ -12803,7 +13119,9 @@ function prepareClaudeLaunch(options) {
|
|
|
12803
13119
|
isIdentityDirectoryName,
|
|
12804
13120
|
isInterceptedHost,
|
|
12805
13121
|
isPrivateAddress,
|
|
13122
|
+
isRcContextUsageDetail,
|
|
12806
13123
|
isRcPermissionMode,
|
|
13124
|
+
isRcReadFileEncoding,
|
|
12807
13125
|
lateRcEventDial,
|
|
12808
13126
|
lateRcStreamDial,
|
|
12809
13127
|
listDirectoryRules,
|
|
@@ -12837,6 +13155,7 @@ function prepareClaudeLaunch(options) {
|
|
|
12837
13155
|
readProfile,
|
|
12838
13156
|
readProvider,
|
|
12839
13157
|
readRcSelfHostRecord,
|
|
13158
|
+
readRcSessionFile,
|
|
12840
13159
|
readUsageSnapshot,
|
|
12841
13160
|
realConnectCertStore,
|
|
12842
13161
|
realConnectEffects,
|
|
@@ -12844,6 +13163,7 @@ function prepareClaudeLaunch(options) {
|
|
|
12844
13163
|
realRcEventDial,
|
|
12845
13164
|
realRcStreamDial,
|
|
12846
13165
|
realRcWebFetch,
|
|
13166
|
+
reconnectRcSessionMcpServer,
|
|
12847
13167
|
recoverFarm,
|
|
12848
13168
|
recoveryDiagnostics,
|
|
12849
13169
|
removeDirectoryRule,
|
|
@@ -12863,6 +13183,7 @@ function prepareClaudeLaunch(options) {
|
|
|
12863
13183
|
runFrontDoorSupervisor,
|
|
12864
13184
|
runLauncher,
|
|
12865
13185
|
runSupervisor,
|
|
13186
|
+
sendRcKeepAlive,
|
|
12866
13187
|
servedByPipeline,
|
|
12867
13188
|
setAllowAmbientCredential,
|
|
12868
13189
|
setDefaultConfigProfile,
|
|
@@ -12878,6 +13199,8 @@ function prepareClaudeLaunch(options) {
|
|
|
12878
13199
|
snapshotPath,
|
|
12879
13200
|
spawnClaude,
|
|
12880
13201
|
startConnectServer,
|
|
13202
|
+
submitRcSessionMcpOAuthCallbackUrl,
|
|
13203
|
+
suggestRcSessionFiles,
|
|
12881
13204
|
topLevelNames,
|
|
12882
13205
|
updateDirectoryRule,
|
|
12883
13206
|
updateProvider,
|