@playwo/opencode-cursor-oauth 0.0.0-dev.762b07a81479 → 0.0.0-dev.825419c3fcde
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/cursor/bidi-session.d.ts +1 -2
- package/dist/cursor/bidi-session.js +153 -138
- package/dist/cursor/index.d.ts +1 -1
- package/dist/cursor/index.js +1 -1
- package/dist/cursor/unary-rpc.d.ts +0 -1
- package/dist/cursor/unary-rpc.js +2 -59
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +3 -0
- package/dist/openai/messages.d.ts +0 -1
- package/dist/openai/messages.js +0 -3
- package/dist/plugin/cursor-auth-plugin.js +0 -1
- package/dist/proxy/bridge-non-streaming.js +1 -3
- package/dist/proxy/bridge-session.js +1 -3
- package/dist/proxy/bridge-streaming.d.ts +1 -1
- package/dist/proxy/bridge-streaming.js +110 -19
- package/dist/proxy/chat-completion.js +44 -12
- package/dist/proxy/cursor-request.js +12 -15
- package/dist/proxy/server.js +23 -5
- package/dist/proxy/stream-dispatch.d.ts +1 -1
- package/dist/proxy/stream-dispatch.js +202 -59
- package/dist/proxy/stream-state.d.ts +0 -2
- package/dist/proxy/types.d.ts +6 -1
- package/package.json +1 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { create, toBinary } from "@bufbuild/protobuf";
|
|
2
|
-
import { AgentClientMessageSchema, ClientHeartbeatSchema, ConversationStateStructureSchema, BackgroundShellSpawnResultSchema, DeleteResultSchema, DeleteRejectedSchema, DiagnosticsResultSchema, ExecClientMessageSchema, FetchErrorSchema, FetchResultSchema, GetBlobResultSchema, GrepErrorSchema, GrepResultSchema, KvClientMessageSchema, LsRejectedSchema, LsResultSchema, McpResultSchema, ReadRejectedSchema, ReadResultSchema, RequestContextResultSchema, RequestContextSchema, RequestContextSuccessSchema, SetBlobResultSchema, ShellRejectedSchema, ShellResultSchema, WriteRejectedSchema, WriteResultSchema, WriteShellStdinErrorSchema, WriteShellStdinResultSchema, } from "../proto/agent_pb";
|
|
2
|
+
import { AgentClientMessageSchema, AskQuestionInteractionResponseSchema, AskQuestionRejectedSchema, AskQuestionResultSchema, ClientHeartbeatSchema, ConversationStateStructureSchema, BackgroundShellSpawnResultSchema, CreatePlanErrorSchema, CreatePlanRequestResponseSchema, CreatePlanResultSchema, DeleteResultSchema, DeleteRejectedSchema, DiagnosticsResultSchema, ExecClientMessageSchema, ExaFetchRequestResponseSchema, ExaFetchRequestResponse_RejectedSchema, ExaSearchRequestResponseSchema, ExaSearchRequestResponse_RejectedSchema, FetchErrorSchema, FetchResultSchema, GetBlobResultSchema, GrepErrorSchema, GrepResultSchema, InteractionResponseSchema, KvClientMessageSchema, LsRejectedSchema, LsResultSchema, McpResultSchema, ReadRejectedSchema, ReadResultSchema, RequestContextResultSchema, RequestContextSchema, RequestContextSuccessSchema, SetBlobResultSchema, ShellRejectedSchema, ShellResultSchema, SwitchModeRequestResponseSchema, SwitchModeRequestResponse_RejectedSchema, WebSearchRequestResponseSchema, WebSearchRequestResponse_RejectedSchema, WriteRejectedSchema, WriteResultSchema, WriteShellStdinErrorSchema, WriteShellStdinResultSchema, } from "../proto/agent_pb";
|
|
3
3
|
import { CONNECT_END_STREAM_FLAG } from "../cursor/config";
|
|
4
|
-
import { logPluginError, logPluginWarn } from "../logger";
|
|
4
|
+
import { logPluginError, logPluginInfo, logPluginWarn } from "../logger";
|
|
5
5
|
import { decodeMcpArgsMap } from "../openai/tools";
|
|
6
6
|
export function parseConnectEndStream(data) {
|
|
7
7
|
try {
|
|
@@ -128,16 +128,16 @@ export function computeUsage(state) {
|
|
|
128
128
|
const prompt_tokens = Math.max(0, total_tokens - completion_tokens);
|
|
129
129
|
return { prompt_tokens, completion_tokens, total_tokens };
|
|
130
130
|
}
|
|
131
|
-
export function processServerMessage(msg, blobStore, mcpTools, sendFrame, state, onText, onMcpExec, onCheckpoint, onTurnEnded, onUnsupportedMessage, onUnhandledExec) {
|
|
131
|
+
export function processServerMessage(msg, blobStore, cloudRule, mcpTools, sendFrame, state, onText, onMcpExec, onCheckpoint, onTurnEnded, onUnsupportedMessage, onUnhandledExec) {
|
|
132
132
|
const msgCase = msg.message.case;
|
|
133
133
|
if (msgCase === "interactionUpdate") {
|
|
134
|
-
handleInteractionUpdate(msg.message.value, state, onText,
|
|
134
|
+
handleInteractionUpdate(msg.message.value, state, onText, onTurnEnded, onUnsupportedMessage);
|
|
135
135
|
}
|
|
136
136
|
else if (msgCase === "kvServerMessage") {
|
|
137
137
|
handleKvMessage(msg.message.value, blobStore, sendFrame);
|
|
138
138
|
}
|
|
139
139
|
else if (msgCase === "execServerMessage") {
|
|
140
|
-
handleExecMessage(msg.message.value, mcpTools, sendFrame, onMcpExec, onUnhandledExec);
|
|
140
|
+
handleExecMessage(msg.message.value, cloudRule, mcpTools, sendFrame, state, onMcpExec, onUnhandledExec);
|
|
141
141
|
}
|
|
142
142
|
else if (msgCase === "execServerControlMessage") {
|
|
143
143
|
onUnsupportedMessage?.({
|
|
@@ -146,10 +146,7 @@ export function processServerMessage(msg, blobStore, mcpTools, sendFrame, state,
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
else if (msgCase === "interactionQuery") {
|
|
149
|
-
onUnsupportedMessage
|
|
150
|
-
category: "interactionQuery",
|
|
151
|
-
caseName: msg.message.value.query.case ?? "undefined",
|
|
152
|
-
});
|
|
149
|
+
handleInteractionQuery(msg.message.value, sendFrame, onUnsupportedMessage);
|
|
153
150
|
}
|
|
154
151
|
else if (msgCase === "conversationCheckpointUpdate") {
|
|
155
152
|
const stateStructure = msg.message.value;
|
|
@@ -167,8 +164,19 @@ export function processServerMessage(msg, blobStore, mcpTools, sendFrame, state,
|
|
|
167
164
|
});
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
|
-
function handleInteractionUpdate(update, state, onText,
|
|
167
|
+
function handleInteractionUpdate(update, state, onText, onTurnEnded, onUnsupportedMessage) {
|
|
171
168
|
const updateCase = update.message?.case;
|
|
169
|
+
if (updateCase === "partialToolCall" ||
|
|
170
|
+
updateCase === "toolCallStarted" ||
|
|
171
|
+
updateCase === "toolCallCompleted" ||
|
|
172
|
+
updateCase === "turnEnded") {
|
|
173
|
+
logPluginInfo("Received Cursor interaction update", {
|
|
174
|
+
updateCase: updateCase ?? "undefined",
|
|
175
|
+
callId: update.message?.value?.callId,
|
|
176
|
+
modelCallId: update.message?.value?.modelCallId,
|
|
177
|
+
toolCase: update.message?.value?.toolCall?.tool?.case,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
172
180
|
if (updateCase === "textDelta") {
|
|
173
181
|
const delta = update.message.value.text || "";
|
|
174
182
|
if (delta)
|
|
@@ -183,20 +191,17 @@ function handleInteractionUpdate(update, state, onText, onMcpExec, onTurnEnded,
|
|
|
183
191
|
state.outputTokens += update.message.value.tokens ?? 0;
|
|
184
192
|
}
|
|
185
193
|
else if (updateCase === "partialToolCall") {
|
|
186
|
-
|
|
187
|
-
if (partial.callId && partial.argsTextDelta) {
|
|
188
|
-
state.interactionToolArgsText.set(partial.callId, partial.argsTextDelta);
|
|
189
|
-
}
|
|
194
|
+
return;
|
|
190
195
|
}
|
|
191
196
|
else if (updateCase === "toolCallCompleted") {
|
|
192
|
-
const
|
|
193
|
-
if (
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
const toolValue = update.message.value;
|
|
198
|
+
if (toolValue?.toolCall?.tool?.case === "mcpToolCall") {
|
|
199
|
+
logPluginInfo("Ignoring Cursor interaction MCP tool completion", {
|
|
200
|
+
callId: toolValue.callId,
|
|
201
|
+
modelCallId: toolValue.modelCallId,
|
|
202
|
+
toolCallId: toolValue.toolCall.tool.value?.args?.toolCallId || toolValue.callId,
|
|
203
|
+
toolName: toolValue.toolCall.tool.value?.args?.toolName ||
|
|
204
|
+
toolValue.toolCall.tool.value?.args?.name,
|
|
200
205
|
});
|
|
201
206
|
}
|
|
202
207
|
}
|
|
@@ -221,42 +226,92 @@ function handleInteractionUpdate(update, state, onText, onMcpExec, onTurnEnded,
|
|
|
221
226
|
caseName: updateCase ?? "undefined",
|
|
222
227
|
});
|
|
223
228
|
}
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
// message path (mcpArgs → mcpResult), not interaction updates.
|
|
229
|
+
// Interaction tool-call updates are informational only. Resumable MCP tool
|
|
230
|
+
// execution comes from execServerMessage.mcpArgs.
|
|
227
231
|
}
|
|
228
|
-
function
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
232
|
+
function handleInteractionQuery(query, sendFrame, onUnsupportedMessage) {
|
|
233
|
+
const queryCase = query.query.case;
|
|
234
|
+
if (queryCase === "webSearchRequestQuery") {
|
|
235
|
+
const response = create(WebSearchRequestResponseSchema, {
|
|
236
|
+
result: {
|
|
237
|
+
case: "rejected",
|
|
238
|
+
value: create(WebSearchRequestResponse_RejectedSchema, {
|
|
239
|
+
reason: "Native Cursor web search is not available in this environment. Use the provided MCP tool `websearch` instead.",
|
|
240
|
+
}),
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
sendInteractionResponse(query.id, "webSearchRequestResponse", response, sendFrame);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (queryCase === "askQuestionInteractionQuery") {
|
|
247
|
+
const response = create(AskQuestionInteractionResponseSchema, {
|
|
248
|
+
result: create(AskQuestionResultSchema, {
|
|
249
|
+
result: {
|
|
250
|
+
case: "rejected",
|
|
251
|
+
value: create(AskQuestionRejectedSchema, {
|
|
252
|
+
reason: "Native Cursor question prompts are not available in this environment. Use the provided MCP tool `question` instead.",
|
|
253
|
+
}),
|
|
254
|
+
},
|
|
255
|
+
}),
|
|
256
|
+
});
|
|
257
|
+
sendInteractionResponse(query.id, "askQuestionInteractionResponse", response, sendFrame);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (queryCase === "switchModeRequestQuery") {
|
|
261
|
+
const response = create(SwitchModeRequestResponseSchema, {
|
|
262
|
+
result: {
|
|
263
|
+
case: "rejected",
|
|
264
|
+
value: create(SwitchModeRequestResponse_RejectedSchema, {
|
|
265
|
+
reason: "Cursor mode switching is not available in this environment. Continue using the current agent and the provided MCP tools.",
|
|
266
|
+
}),
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
sendInteractionResponse(query.id, "switchModeRequestResponse", response, sendFrame);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (queryCase === "exaSearchRequestQuery") {
|
|
273
|
+
const response = create(ExaSearchRequestResponseSchema, {
|
|
274
|
+
result: {
|
|
275
|
+
case: "rejected",
|
|
276
|
+
value: create(ExaSearchRequestResponse_RejectedSchema, {
|
|
277
|
+
reason: "Native Cursor Exa search is not available in this environment. Use the provided MCP tool `websearch` instead.",
|
|
278
|
+
}),
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
sendInteractionResponse(query.id, "exaSearchRequestResponse", response, sendFrame);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (queryCase === "exaFetchRequestQuery") {
|
|
285
|
+
const response = create(ExaFetchRequestResponseSchema, {
|
|
286
|
+
result: {
|
|
287
|
+
case: "rejected",
|
|
288
|
+
value: create(ExaFetchRequestResponse_RejectedSchema, {
|
|
289
|
+
reason: "Native Cursor Exa fetch is not available in this environment. Use the provided MCP tools `websearch` and `webfetch` instead.",
|
|
290
|
+
}),
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
sendInteractionResponse(query.id, "exaFetchRequestResponse", response, sendFrame);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (queryCase === "createPlanRequestQuery") {
|
|
297
|
+
const response = create(CreatePlanRequestResponseSchema, {
|
|
298
|
+
result: create(CreatePlanResultSchema, {
|
|
299
|
+
planUri: "",
|
|
300
|
+
result: {
|
|
301
|
+
case: "error",
|
|
302
|
+
value: create(CreatePlanErrorSchema, {
|
|
303
|
+
error: "Native Cursor plan creation is not available in this environment. Use the provided MCP planning tools instead.",
|
|
304
|
+
}),
|
|
305
|
+
},
|
|
306
|
+
}),
|
|
307
|
+
});
|
|
308
|
+
sendInteractionResponse(query.id, "createPlanRequestResponse", response, sendFrame);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
onUnsupportedMessage?.({
|
|
312
|
+
category: "interactionQuery",
|
|
313
|
+
caseName: queryCase ?? "undefined",
|
|
314
|
+
});
|
|
260
315
|
}
|
|
261
316
|
/** Send a KV client response back to Cursor. */
|
|
262
317
|
function sendKvResponse(kvMsg, messageCase, value, sendFrame) {
|
|
@@ -269,6 +324,16 @@ function sendKvResponse(kvMsg, messageCase, value, sendFrame) {
|
|
|
269
324
|
});
|
|
270
325
|
sendFrame(toBinary(AgentClientMessageSchema, clientMsg));
|
|
271
326
|
}
|
|
327
|
+
function sendInteractionResponse(queryId, messageCase, value, sendFrame) {
|
|
328
|
+
const response = create(InteractionResponseSchema, {
|
|
329
|
+
id: queryId,
|
|
330
|
+
result: { case: messageCase, value: value },
|
|
331
|
+
});
|
|
332
|
+
const clientMessage = create(AgentClientMessageSchema, {
|
|
333
|
+
message: { case: "interactionResponse", value: response },
|
|
334
|
+
});
|
|
335
|
+
sendFrame(toBinary(AgentClientMessageSchema, clientMessage));
|
|
336
|
+
}
|
|
272
337
|
function handleKvMessage(kvMsg, blobStore, sendFrame) {
|
|
273
338
|
const kvCase = kvMsg.message.case;
|
|
274
339
|
if (kvCase === "getBlobArgs") {
|
|
@@ -289,9 +354,19 @@ function handleKvMessage(kvMsg, blobStore, sendFrame) {
|
|
|
289
354
|
sendKvResponse(kvMsg, "setBlobResult", create(SetBlobResultSchema, {}), sendFrame);
|
|
290
355
|
}
|
|
291
356
|
}
|
|
292
|
-
function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledExec) {
|
|
357
|
+
function handleExecMessage(execMsg, cloudRule, mcpTools, sendFrame, state, onMcpExec, onUnhandledExec) {
|
|
293
358
|
const execCase = execMsg.message.case;
|
|
359
|
+
logPluginInfo("Received Cursor exec message", {
|
|
360
|
+
execCase: execCase ?? "undefined",
|
|
361
|
+
execId: execMsg.execId,
|
|
362
|
+
execMsgId: execMsg.id,
|
|
363
|
+
});
|
|
294
364
|
if (execCase === "requestContextArgs") {
|
|
365
|
+
logPluginInfo("Responding to Cursor requestContextArgs", {
|
|
366
|
+
execId: execMsg.execId,
|
|
367
|
+
execMsgId: execMsg.id,
|
|
368
|
+
mcpToolCount: mcpTools.length,
|
|
369
|
+
});
|
|
295
370
|
const requestContext = create(RequestContextSchema, {
|
|
296
371
|
rules: [],
|
|
297
372
|
repositoryInfo: [],
|
|
@@ -299,6 +374,7 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
299
374
|
gitRepos: [],
|
|
300
375
|
projectLayouts: [],
|
|
301
376
|
mcpInstructions: [],
|
|
377
|
+
cloudRule,
|
|
302
378
|
fileContents: {},
|
|
303
379
|
customSubagents: [],
|
|
304
380
|
});
|
|
@@ -314,13 +390,23 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
314
390
|
if (execCase === "mcpArgs") {
|
|
315
391
|
const mcpArgs = execMsg.message.value;
|
|
316
392
|
const decoded = decodeMcpArgsMap(mcpArgs.args ?? {});
|
|
317
|
-
|
|
393
|
+
const exec = {
|
|
318
394
|
execId: execMsg.execId,
|
|
319
395
|
execMsgId: execMsg.id,
|
|
320
396
|
toolCallId: mcpArgs.toolCallId || crypto.randomUUID(),
|
|
321
397
|
toolName: mcpArgs.toolName || mcpArgs.name,
|
|
322
398
|
decodedArgs: JSON.stringify(decoded),
|
|
399
|
+
source: "exec",
|
|
400
|
+
};
|
|
401
|
+
logPluginInfo("Received Cursor exec MCP tool metadata", {
|
|
402
|
+
toolCallId: exec.toolCallId,
|
|
403
|
+
toolName: exec.toolName,
|
|
404
|
+
source: exec.source,
|
|
405
|
+
execId: exec.execId,
|
|
406
|
+
execMsgId: exec.execMsgId,
|
|
407
|
+
decodedArgs: exec.decodedArgs,
|
|
323
408
|
});
|
|
409
|
+
onMcpExec(exec);
|
|
324
410
|
return;
|
|
325
411
|
}
|
|
326
412
|
// --- Reject native Cursor tools ---
|
|
@@ -328,6 +414,11 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
328
414
|
// so it falls back to our MCP tools (registered via RequestContext).
|
|
329
415
|
const REJECT_REASON = "Tool not available in this environment. Use the MCP tools provided instead.";
|
|
330
416
|
if (execCase === "readArgs") {
|
|
417
|
+
logPluginInfo("Rejecting native Cursor read tool in favor of MCP", {
|
|
418
|
+
execId: execMsg.execId,
|
|
419
|
+
execMsgId: execMsg.id,
|
|
420
|
+
path: execMsg.message.value.path,
|
|
421
|
+
});
|
|
331
422
|
const args = execMsg.message.value;
|
|
332
423
|
const result = create(ReadResultSchema, {
|
|
333
424
|
result: {
|
|
@@ -342,6 +433,11 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
342
433
|
return;
|
|
343
434
|
}
|
|
344
435
|
if (execCase === "lsArgs") {
|
|
436
|
+
logPluginInfo("Rejecting native Cursor ls tool in favor of MCP", {
|
|
437
|
+
execId: execMsg.execId,
|
|
438
|
+
execMsgId: execMsg.id,
|
|
439
|
+
path: execMsg.message.value.path,
|
|
440
|
+
});
|
|
345
441
|
const args = execMsg.message.value;
|
|
346
442
|
const result = create(LsResultSchema, {
|
|
347
443
|
result: {
|
|
@@ -356,6 +452,10 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
356
452
|
return;
|
|
357
453
|
}
|
|
358
454
|
if (execCase === "grepArgs") {
|
|
455
|
+
logPluginInfo("Rejecting native Cursor grep tool in favor of MCP", {
|
|
456
|
+
execId: execMsg.execId,
|
|
457
|
+
execMsgId: execMsg.id,
|
|
458
|
+
});
|
|
359
459
|
const result = create(GrepResultSchema, {
|
|
360
460
|
result: {
|
|
361
461
|
case: "error",
|
|
@@ -366,6 +466,11 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
366
466
|
return;
|
|
367
467
|
}
|
|
368
468
|
if (execCase === "writeArgs") {
|
|
469
|
+
logPluginInfo("Rejecting native Cursor write tool in favor of MCP", {
|
|
470
|
+
execId: execMsg.execId,
|
|
471
|
+
execMsgId: execMsg.id,
|
|
472
|
+
path: execMsg.message.value.path,
|
|
473
|
+
});
|
|
369
474
|
const args = execMsg.message.value;
|
|
370
475
|
const result = create(WriteResultSchema, {
|
|
371
476
|
result: {
|
|
@@ -380,6 +485,11 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
380
485
|
return;
|
|
381
486
|
}
|
|
382
487
|
if (execCase === "deleteArgs") {
|
|
488
|
+
logPluginInfo("Rejecting native Cursor delete tool in favor of MCP", {
|
|
489
|
+
execId: execMsg.execId,
|
|
490
|
+
execMsgId: execMsg.id,
|
|
491
|
+
path: execMsg.message.value.path,
|
|
492
|
+
});
|
|
383
493
|
const args = execMsg.message.value;
|
|
384
494
|
const result = create(DeleteResultSchema, {
|
|
385
495
|
result: {
|
|
@@ -394,6 +504,13 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
394
504
|
return;
|
|
395
505
|
}
|
|
396
506
|
if (execCase === "shellArgs" || execCase === "shellStreamArgs") {
|
|
507
|
+
logPluginInfo("Rejecting native Cursor shell tool in favor of MCP", {
|
|
508
|
+
execId: execMsg.execId,
|
|
509
|
+
execMsgId: execMsg.id,
|
|
510
|
+
command: execMsg.message.value.command ?? "",
|
|
511
|
+
workingDirectory: execMsg.message.value.workingDirectory ?? "",
|
|
512
|
+
execCase,
|
|
513
|
+
});
|
|
397
514
|
const args = execMsg.message.value;
|
|
398
515
|
const result = create(ShellResultSchema, {
|
|
399
516
|
result: {
|
|
@@ -410,6 +527,12 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
410
527
|
return;
|
|
411
528
|
}
|
|
412
529
|
if (execCase === "backgroundShellSpawnArgs") {
|
|
530
|
+
logPluginInfo("Rejecting native Cursor background shell tool in favor of MCP", {
|
|
531
|
+
execId: execMsg.execId,
|
|
532
|
+
execMsgId: execMsg.id,
|
|
533
|
+
command: execMsg.message.value.command ?? "",
|
|
534
|
+
workingDirectory: execMsg.message.value.workingDirectory ?? "",
|
|
535
|
+
});
|
|
413
536
|
const args = execMsg.message.value;
|
|
414
537
|
const result = create(BackgroundShellSpawnResultSchema, {
|
|
415
538
|
result: {
|
|
@@ -426,6 +549,10 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
426
549
|
return;
|
|
427
550
|
}
|
|
428
551
|
if (execCase === "writeShellStdinArgs") {
|
|
552
|
+
logPluginInfo("Rejecting native Cursor shell stdin tool in favor of MCP", {
|
|
553
|
+
execId: execMsg.execId,
|
|
554
|
+
execMsgId: execMsg.id,
|
|
555
|
+
});
|
|
429
556
|
const result = create(WriteShellStdinResultSchema, {
|
|
430
557
|
result: {
|
|
431
558
|
case: "error",
|
|
@@ -436,6 +563,11 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
436
563
|
return;
|
|
437
564
|
}
|
|
438
565
|
if (execCase === "fetchArgs") {
|
|
566
|
+
logPluginInfo("Rejecting native Cursor fetch tool in favor of MCP", {
|
|
567
|
+
execId: execMsg.execId,
|
|
568
|
+
execMsgId: execMsg.id,
|
|
569
|
+
url: execMsg.message.value.url,
|
|
570
|
+
});
|
|
439
571
|
const args = execMsg.message.value;
|
|
440
572
|
const result = create(FetchResultSchema, {
|
|
441
573
|
result: {
|
|
@@ -450,6 +582,11 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
450
582
|
return;
|
|
451
583
|
}
|
|
452
584
|
if (execCase === "diagnosticsArgs") {
|
|
585
|
+
logPluginInfo("Rejecting native Cursor diagnostics tool in favor of MCP", {
|
|
586
|
+
execId: execMsg.execId,
|
|
587
|
+
execMsgId: execMsg.id,
|
|
588
|
+
path: execMsg.message.value.path,
|
|
589
|
+
});
|
|
453
590
|
const result = create(DiagnosticsResultSchema, {});
|
|
454
591
|
sendExecResult(execMsg, "diagnosticsResult", result, sendFrame);
|
|
455
592
|
return;
|
|
@@ -463,6 +600,12 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
463
600
|
};
|
|
464
601
|
const resultCase = miscCaseMap[execCase];
|
|
465
602
|
if (resultCase) {
|
|
603
|
+
logPluginInfo("Responding to miscellaneous Cursor exec message", {
|
|
604
|
+
execCase,
|
|
605
|
+
execId: execMsg.execId,
|
|
606
|
+
execMsgId: execMsg.id,
|
|
607
|
+
resultCase,
|
|
608
|
+
});
|
|
466
609
|
sendExecResult(execMsg, resultCase, create(McpResultSchema, {}), sendFrame);
|
|
467
610
|
return;
|
|
468
611
|
}
|
package/dist/proxy/types.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { CursorSession } from "../cursor/bidi-session";
|
|
2
|
-
import type { ConversationRequestMetadata } from "./conversation-meta";
|
|
3
2
|
import type { McpToolDefinition } from "../proto/agent_pb";
|
|
3
|
+
import type { ConversationRequestMetadata } from "./conversation-meta";
|
|
4
4
|
export interface CursorRequestPayload {
|
|
5
5
|
requestBytes: Uint8Array;
|
|
6
6
|
blobStore: Map<string, Uint8Array>;
|
|
7
|
+
cloudRule?: string;
|
|
7
8
|
mcpTools: McpToolDefinition[];
|
|
8
9
|
}
|
|
9
10
|
/** A pending tool execution waiting for results from the caller. */
|
|
@@ -14,12 +15,16 @@ export interface PendingExec {
|
|
|
14
15
|
toolName: string;
|
|
15
16
|
/** Decoded arguments JSON string for SSE tool_calls emission. */
|
|
16
17
|
decodedArgs: string;
|
|
18
|
+
source?: "interaction" | "exec";
|
|
19
|
+
cursorCallId?: string;
|
|
20
|
+
modelCallId?: string;
|
|
17
21
|
}
|
|
18
22
|
/** A live Cursor session kept alive across requests for tool result continuation. */
|
|
19
23
|
export interface ActiveBridge {
|
|
20
24
|
bridge: CursorSession;
|
|
21
25
|
heartbeatTimer: NodeJS.Timeout;
|
|
22
26
|
blobStore: Map<string, Uint8Array>;
|
|
27
|
+
cloudRule?: string;
|
|
23
28
|
mcpTools: McpToolDefinition[];
|
|
24
29
|
pendingExecs: PendingExec[];
|
|
25
30
|
modelId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playwo/opencode-cursor-oauth",
|
|
3
|
-
"version": "0.0.0-dev.
|
|
3
|
+
"version": "0.0.0-dev.825419c3fcde",
|
|
4
4
|
"description": "OpenCode plugin that connects Cursor's API to OpenCode via OAuth, model discovery, and a local OpenAI-compatible proxy.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "tsc -p tsconfig.json",
|
|
22
|
-
"test": "bun test/smoke.ts",
|
|
23
22
|
"prepublishOnly": "npm run build"
|
|
24
23
|
},
|
|
25
24
|
"repository": {
|