@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.
@@ -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, onMcpExec, onTurnEnded, onUnsupportedMessage);
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, onMcpExec, onTurnEnded, onUnsupportedMessage) {
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
- const partial = update.message.value;
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 exec = decodeInteractionToolCall(update.message.value, state);
193
- if (exec)
194
- onMcpExec(exec);
195
- else {
196
- onUnsupportedMessage?.({
197
- category: "toolCall",
198
- caseName: update.message.value?.toolCall?.tool?.case ?? "undefined",
199
- detail: "toolCallCompleted",
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
- // toolCallStarted, partialToolCall, toolCallDelta, toolCallCompleted
225
- // are intentionally ignored. MCP tool calls flow through the exec
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 decodeInteractionToolCall(update, state) {
229
- const callId = update.callId ?? "";
230
- const toolCase = update.toolCall?.tool?.case;
231
- if (toolCase !== "mcpToolCall")
232
- return null;
233
- const mcpArgs = update.toolCall?.tool?.value?.args;
234
- if (!mcpArgs)
235
- return null;
236
- const toolCallId = mcpArgs.toolCallId || callId || crypto.randomUUID();
237
- if (state.emittedToolCallIds.has(toolCallId))
238
- return null;
239
- const decodedMap = decodeMcpArgsMap(mcpArgs.args ?? {});
240
- const partialArgsText = callId
241
- ? state.interactionToolArgsText.get(callId)?.trim()
242
- : undefined;
243
- let decodedArgs = "{}";
244
- if (Object.keys(decodedMap).length > 0) {
245
- decodedArgs = JSON.stringify(decodedMap);
246
- }
247
- else if (partialArgsText) {
248
- decodedArgs = partialArgsText;
249
- }
250
- state.emittedToolCallIds.add(toolCallId);
251
- if (callId)
252
- state.interactionToolArgsText.delete(callId);
253
- return {
254
- execId: callId || toolCallId,
255
- execMsgId: 0,
256
- toolCallId,
257
- toolName: mcpArgs.toolName || mcpArgs.name || "unknown_mcp_tool",
258
- decodedArgs,
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
- onMcpExec({
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
  }
@@ -4,6 +4,4 @@ export interface StreamState {
4
4
  pendingExecs: PendingExec[];
5
5
  outputTokens: number;
6
6
  totalTokens: number;
7
- interactionToolArgsText: Map<string, string>;
8
- emittedToolCallIds: Set<string>;
9
7
  }
@@ -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.762b07a81479",
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": {