@playwo/opencode-cursor-oauth 0.0.0-dev.4463bb589222 → 0.0.0-dev.6338d5591e37
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.
|
@@ -103,7 +103,6 @@ function createBridgeStreamResponse(bridge, heartbeatTimer, blobStore, mcpTools,
|
|
|
103
103
|
sendSSE(makeChunk({ content }));
|
|
104
104
|
}
|
|
105
105
|
}, (exec) => {
|
|
106
|
-
state.pendingExecs.push(exec);
|
|
107
106
|
mcpExecReceived = true;
|
|
108
107
|
const flushed = tagFilter.flush();
|
|
109
108
|
if (flushed.reasoning)
|
|
@@ -128,6 +128,51 @@ 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
|
+
function getPendingExecKey(exec) {
|
|
132
|
+
return exec.toolCallId || `${exec.toolName}:${exec.decodedArgs}`;
|
|
133
|
+
}
|
|
134
|
+
function replacePendingExec(state, exec) {
|
|
135
|
+
const execKey = getPendingExecKey(exec);
|
|
136
|
+
const existingIndex = state.pendingExecs.findIndex((candidate) => getPendingExecKey(candidate) === execKey);
|
|
137
|
+
if (existingIndex >= 0) {
|
|
138
|
+
state.pendingExecs[existingIndex] = exec;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
state.pendingExecs.push(exec);
|
|
142
|
+
}
|
|
143
|
+
function hasUsableDecodedArgs(decodedArgs) {
|
|
144
|
+
const trimmed = decodedArgs.trim();
|
|
145
|
+
return trimmed !== "" && trimmed !== "{}";
|
|
146
|
+
}
|
|
147
|
+
function mergePendingExec(existing, incoming) {
|
|
148
|
+
const incomingHasExecMetadata = incoming.execMsgId !== 0;
|
|
149
|
+
const existingHasExecMetadata = existing.execMsgId !== 0;
|
|
150
|
+
return {
|
|
151
|
+
execId: incomingHasExecMetadata || !existing.execId ? incoming.execId : existing.execId,
|
|
152
|
+
execMsgId: incomingHasExecMetadata || !existingHasExecMetadata
|
|
153
|
+
? incoming.execMsgId
|
|
154
|
+
: existing.execMsgId,
|
|
155
|
+
toolCallId: existing.toolCallId || incoming.toolCallId,
|
|
156
|
+
toolName: incoming.toolName && incoming.toolName !== "unknown_mcp_tool"
|
|
157
|
+
? incoming.toolName
|
|
158
|
+
: existing.toolName,
|
|
159
|
+
decodedArgs: hasUsableDecodedArgs(incoming.decodedArgs)
|
|
160
|
+
? incoming.decodedArgs
|
|
161
|
+
: existing.decodedArgs,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function emitPendingExec(exec, state, onMcpExec) {
|
|
165
|
+
const execKey = getPendingExecKey(exec);
|
|
166
|
+
const existing = state.pendingExecs.find((candidate) => getPendingExecKey(candidate) === execKey);
|
|
167
|
+
const nextExec = existing ? mergePendingExec(existing, exec) : exec;
|
|
168
|
+
if (state.emittedToolCallIds.has(execKey)) {
|
|
169
|
+
replacePendingExec(state, nextExec);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
state.emittedToolCallIds.add(execKey);
|
|
173
|
+
replacePendingExec(state, nextExec);
|
|
174
|
+
onMcpExec(nextExec);
|
|
175
|
+
}
|
|
131
176
|
export function processServerMessage(msg, blobStore, mcpTools, sendFrame, state, onText, onMcpExec, onCheckpoint, onTurnEnded, onUnsupportedMessage, onUnhandledExec) {
|
|
132
177
|
const msgCase = msg.message.case;
|
|
133
178
|
if (msgCase === "interactionUpdate") {
|
|
@@ -137,7 +182,7 @@ export function processServerMessage(msg, blobStore, mcpTools, sendFrame, state,
|
|
|
137
182
|
handleKvMessage(msg.message.value, blobStore, sendFrame);
|
|
138
183
|
}
|
|
139
184
|
else if (msgCase === "execServerMessage") {
|
|
140
|
-
handleExecMessage(msg.message.value, mcpTools, sendFrame, onMcpExec, onUnhandledExec);
|
|
185
|
+
handleExecMessage(msg.message.value, mcpTools, sendFrame, state, onMcpExec, onUnhandledExec);
|
|
141
186
|
}
|
|
142
187
|
else if (msgCase === "execServerControlMessage") {
|
|
143
188
|
onUnsupportedMessage?.({
|
|
@@ -182,13 +227,14 @@ function handleInteractionUpdate(update, state, onText, onMcpExec, onTurnEnded,
|
|
|
182
227
|
else if (updateCase === "partialToolCall") {
|
|
183
228
|
const partial = update.message.value;
|
|
184
229
|
if (partial.callId && partial.argsTextDelta) {
|
|
185
|
-
state.interactionToolArgsText.
|
|
230
|
+
const existing = state.interactionToolArgsText.get(partial.callId) ?? "";
|
|
231
|
+
state.interactionToolArgsText.set(partial.callId, `${existing}${partial.argsTextDelta}`);
|
|
186
232
|
}
|
|
187
233
|
}
|
|
188
234
|
else if (updateCase === "toolCallCompleted") {
|
|
189
235
|
const exec = decodeInteractionToolCall(update.message.value, state);
|
|
190
236
|
if (exec)
|
|
191
|
-
|
|
237
|
+
emitPendingExec(exec, state, onMcpExec);
|
|
192
238
|
}
|
|
193
239
|
else if (updateCase === "turnEnded") {
|
|
194
240
|
onTurnEnded?.();
|
|
@@ -225,8 +271,6 @@ function decodeInteractionToolCall(update, state) {
|
|
|
225
271
|
if (!mcpArgs)
|
|
226
272
|
return null;
|
|
227
273
|
const toolCallId = mcpArgs.toolCallId || callId || crypto.randomUUID();
|
|
228
|
-
if (state.emittedToolCallIds.has(toolCallId))
|
|
229
|
-
return null;
|
|
230
274
|
const decodedMap = decodeMcpArgsMap(mcpArgs.args ?? {});
|
|
231
275
|
const partialArgsText = callId
|
|
232
276
|
? state.interactionToolArgsText.get(callId)?.trim()
|
|
@@ -238,7 +282,6 @@ function decodeInteractionToolCall(update, state) {
|
|
|
238
282
|
else if (partialArgsText) {
|
|
239
283
|
decodedArgs = partialArgsText;
|
|
240
284
|
}
|
|
241
|
-
state.emittedToolCallIds.add(toolCallId);
|
|
242
285
|
if (callId)
|
|
243
286
|
state.interactionToolArgsText.delete(callId);
|
|
244
287
|
return {
|
|
@@ -374,7 +417,7 @@ function handleKvMessage(kvMsg, blobStore, sendFrame) {
|
|
|
374
417
|
sendKvResponse(kvMsg, "setBlobResult", create(SetBlobResultSchema, {}), sendFrame);
|
|
375
418
|
}
|
|
376
419
|
}
|
|
377
|
-
function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledExec) {
|
|
420
|
+
function handleExecMessage(execMsg, mcpTools, sendFrame, state, onMcpExec, onUnhandledExec) {
|
|
378
421
|
const execCase = execMsg.message.case;
|
|
379
422
|
if (execCase === "requestContextArgs") {
|
|
380
423
|
const requestContext = create(RequestContextSchema, {
|
|
@@ -399,13 +442,14 @@ function handleExecMessage(execMsg, mcpTools, sendFrame, onMcpExec, onUnhandledE
|
|
|
399
442
|
if (execCase === "mcpArgs") {
|
|
400
443
|
const mcpArgs = execMsg.message.value;
|
|
401
444
|
const decoded = decodeMcpArgsMap(mcpArgs.args ?? {});
|
|
402
|
-
|
|
445
|
+
const exec = {
|
|
403
446
|
execId: execMsg.execId,
|
|
404
447
|
execMsgId: execMsg.id,
|
|
405
448
|
toolCallId: mcpArgs.toolCallId || crypto.randomUUID(),
|
|
406
449
|
toolName: mcpArgs.toolName || mcpArgs.name,
|
|
407
450
|
decodedArgs: JSON.stringify(decoded),
|
|
408
|
-
}
|
|
451
|
+
};
|
|
452
|
+
emitPendingExec(exec, state, onMcpExec);
|
|
409
453
|
return;
|
|
410
454
|
}
|
|
411
455
|
// --- Reject native Cursor tools ---
|
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.6338d5591e37",
|
|
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",
|