@magpie-community/opencode-cursor-auth 0.2.34 → 0.2.35
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 +9 -3
- package/index.mjs +41 -9
- package/native-session.mjs +119 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,8 +123,11 @@ caller's tool results is bounded by the 120 seconds above instead.
|
|
|
123
123
|
|
|
124
124
|
Cursor's count of a step's tool calls includes calls the plugin answers itself:
|
|
125
125
|
a tool the request doesn't have is refused to the model, and Cursor's own
|
|
126
|
-
`get_mcp_tools` is answered with the request's tools.
|
|
127
|
-
|
|
126
|
+
`get_mcp_tools` is answered with the request's tools. It also includes calls
|
|
127
|
+
Cursor completes by itself, which it writes and completes in the step but never
|
|
128
|
+
starts on the client or sends to it; those count toward it too. Once the count
|
|
129
|
+
has come, a checkpoint whose state waits on exactly the calls the caller was
|
|
130
|
+
given also ends the step (#550). The step's calls are the rest.
|
|
128
131
|
|
|
129
132
|
These are retention limits. A missing, expired, restarted, busy, incompatible,
|
|
130
133
|
or full owner uses the original history reconstruction and stateless decoder
|
|
@@ -312,7 +315,10 @@ portable data folder. The newest 20 are kept. A file holds the Run's
|
|
|
312
315
|
frames in order, both ways, as each frame's time (ms from the Run's
|
|
313
316
|
start), size, kind (text, thinking, checkpoint, heartbeat, ...), field
|
|
314
317
|
numbers and sizes, and the field numbers and sizes one level inside them,
|
|
315
|
-
plus the error and the model id.
|
|
318
|
+
plus the error and the model id. A few of Cursor's numbers are kept too: a
|
|
319
|
+
tool count's value, which kind of call (the field number of Cursor's tool
|
|
320
|
+
call) a call update is about, how many calls a checkpoint waits on, and,
|
|
321
|
+
for a Run that went without the native session, why. No prompt, reply or thinking text, tool
|
|
316
322
|
name or argument, blob or checkpoint content, token, header, account or
|
|
317
323
|
conversation id is written; the error's message has anything shaped like
|
|
318
324
|
an email, id or token taken out. Look the file over before you attach it.
|
package/index.mjs
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
//
|
|
29
29
|
// OpenCode speaks chat completions to it (@ai-sdk/openai-compatible); the
|
|
30
30
|
// fetch here answers them.
|
|
31
|
-
import { NATIVE_LIMITS, nativeSessions, NativeSessionError, nativeFields, nativeMcpArgs, Quiet, setWireTrace } from "./native-session.mjs"
|
|
31
|
+
import { NATIVE_LIMITS, nativeSessions, NativeSessionError, nativeFields, nativeMcpArgs, pendingCalls, Quiet, setWireTrace, StepCalls } from "./native-session.mjs"
|
|
32
32
|
import { isDeepStrictEqual } from "node:util"
|
|
33
33
|
import http2 from "node:http2"
|
|
34
34
|
import { STATUS_CODES } from "node:http"
|
|
@@ -2747,7 +2747,7 @@ async function runNative({ tok, base, id, tools, conv, convID, signal, maxMode,
|
|
|
2747
2747
|
|
|
2748
2748
|
// runOnce is one Run of the chat on the agent API at base: an async
|
|
2749
2749
|
// iterator of the answer's pieces, or the error it failed with before any.
|
|
2750
|
-
async function runOnce({ tok, base, id, tools, conv, convID, signal, maxMode, params }) {
|
|
2750
|
+
async function runOnce({ tok, base, id, tools, conv, convID, signal, maxMode, params, why }) {
|
|
2751
2751
|
// the Run's conversation_id, a new one when nothing names the session:
|
|
2752
2752
|
// its usage event is found by it
|
|
2753
2753
|
const cid = convID || randomUUID()
|
|
@@ -2778,7 +2778,7 @@ async function runOnce({ tok, base, id, tools, conv, convID, signal, maxMode, pa
|
|
|
2778
2778
|
let closed = false
|
|
2779
2779
|
let heartbeat
|
|
2780
2780
|
// a Run Cursor stops answering ends, as a retained one does (#2672)
|
|
2781
|
-
const quiet = new Quiet(NATIVE_LIMITS, () => close(), { path: "stateless", model: id })
|
|
2781
|
+
const quiet = new Quiet(NATIVE_LIMITS, () => close(), { path: "stateless", model: id, why })
|
|
2782
2782
|
const send = (msg) => {
|
|
2783
2783
|
if (!closed && !req.destroyed && req.writable) {
|
|
2784
2784
|
quiet.trace?.frame("out", msg)
|
|
@@ -2822,6 +2822,7 @@ async function runOnce({ tok, base, id, tools, conv, convID, signal, maxMode, pa
|
|
|
2822
2822
|
close,
|
|
2823
2823
|
stepUsage: book.own,
|
|
2824
2824
|
owedUsage: book.owed,
|
|
2825
|
+
note: (name) => quiet.trace?.event(name),
|
|
2825
2826
|
})
|
|
2826
2827
|
const wrapped = (async function* () {
|
|
2827
2828
|
try {
|
|
@@ -2852,7 +2853,7 @@ async function runOnce({ tok, base, id, tools, conv, convID, signal, maxMode, pa
|
|
|
2852
2853
|
|
|
2853
2854
|
// decode follows the server's messages into the answer's pieces until the
|
|
2854
2855
|
// turn ends, or the model has made its tool calls.
|
|
2855
|
-
async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage, owedUsage }) {
|
|
2856
|
+
async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage, owedUsage, note }) {
|
|
2856
2857
|
let calls = 0
|
|
2857
2858
|
// answered: the step's calls answered here (a refusal, the MCP tool
|
|
2858
2859
|
// list), which Cursor's count of the step's calls takes in too (#142)
|
|
@@ -2860,14 +2861,18 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
2860
2861
|
// ended: Cursor said what the turn used
|
|
2861
2862
|
let ended = false
|
|
2862
2863
|
let listed = 0
|
|
2864
|
+
// what Cursor said of the step's calls: those it completed by itself
|
|
2865
|
+
// count toward listed too, and never come as an exec (plugins#550)
|
|
2866
|
+
const step = new StepCalls(fields)
|
|
2863
2867
|
// stepDone is whether every call the step listed has come. A step whose
|
|
2864
2868
|
// calls were all answered here goes on on Cursor's side, under a count of
|
|
2865
2869
|
// its own.
|
|
2866
2870
|
const stepDone = () => {
|
|
2867
|
-
if (!listed || calls + answered < listed) return false
|
|
2871
|
+
if (!listed || calls + answered + step.completed < listed) return false
|
|
2868
2872
|
if (calls > 0) return true
|
|
2869
2873
|
listed = 0
|
|
2870
2874
|
answered = 0
|
|
2875
|
+
step.nextStep()
|
|
2871
2876
|
return false
|
|
2872
2877
|
}
|
|
2873
2878
|
let said = 0
|
|
@@ -2984,6 +2989,16 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
2984
2989
|
return
|
|
2985
2990
|
}
|
|
2986
2991
|
break
|
|
2992
|
+
case 2: // a call started on the client
|
|
2993
|
+
case 3: // a call completed: by Cursor itself when it never started here
|
|
2994
|
+
case 7: // a call the model is writing
|
|
2995
|
+
// still named in an empty reply's list: only their ids are read
|
|
2996
|
+
count(seen.updates, u.num)
|
|
2997
|
+
if (step.update(u.num, uf) && (note?.("completed by Cursor"), stepDone())) {
|
|
2998
|
+
yield await settled()
|
|
2999
|
+
return
|
|
3000
|
+
}
|
|
3001
|
+
break
|
|
2987
3002
|
default:
|
|
2988
3003
|
count(seen.updates, u.num)
|
|
2989
3004
|
}
|
|
@@ -2991,6 +3006,7 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
2991
3006
|
break
|
|
2992
3007
|
case 2: {
|
|
2993
3008
|
// exec_server_message: the server asks the client to run something
|
|
3009
|
+
step.exec(m.data)
|
|
2994
3010
|
const call = exec(m.data, tools, send, closeExec, seen.refused)
|
|
2995
3011
|
if (call) {
|
|
2996
3012
|
said += call.args.length
|
|
@@ -3003,6 +3019,18 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
3003
3019
|
}
|
|
3004
3020
|
break
|
|
3005
3021
|
}
|
|
3022
|
+
case 3:
|
|
3023
|
+
// conversation_checkpoint_update: Cursor's state. Once the step
|
|
3024
|
+
// has its count, a state waiting on just the calls handed to the
|
|
3025
|
+
// caller is a step Cursor has finished: what more the count
|
|
3026
|
+
// says will not come (plugins#550)
|
|
3027
|
+
if (listed && calls > 0 && pendingCalls(m.data, fields) === calls) {
|
|
3028
|
+
note?.("waited on")
|
|
3029
|
+
yield await settled()
|
|
3030
|
+
return
|
|
3031
|
+
}
|
|
3032
|
+
count(seen.messages, m.num)
|
|
3033
|
+
break
|
|
3006
3034
|
case 4: {
|
|
3007
3035
|
// kv_server_message: a blob wanted, or one to keep
|
|
3008
3036
|
const kv = fields(m.data)
|
|
@@ -3033,7 +3061,10 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
3033
3061
|
} catch (e) {
|
|
3034
3062
|
// gone quiet is no answer, calls or not: the step's count never came
|
|
3035
3063
|
if (e?.quiet) {
|
|
3036
|
-
|
|
3064
|
+
// with what came of the step's calls, as the native path's batch
|
|
3065
|
+
// error says it (plugins#550)
|
|
3066
|
+
const batch = calls || listed ? `; the step's tool count ${listed || "not sent"}: ${calls} calls came, ${answered} answered here, ${step.completed} completed by Cursor` : ""
|
|
3067
|
+
yield { error: { status: e.status, message: batch ? e.message.replace(/( \(try again\))?$/, batch + "$1") : e.message } }
|
|
3037
3068
|
return
|
|
3038
3069
|
}
|
|
3039
3070
|
if (calls > 0 && /EOF/.test(e?.message ?? "")) {
|
|
@@ -3207,10 +3238,11 @@ async function answerOf(auth, chat, signal, session = "") {
|
|
|
3207
3238
|
// uses the original history builder/decoder without cancelling a live parent.
|
|
3208
3239
|
const native = prepared.fallback ? null : nativeSessions.create(prepared, { id, maxMode, params }, { pb, exec, usageOf, failure })
|
|
3209
3240
|
const args = { tok, base, id, tools, conv, convID, signal, maxMode, params }
|
|
3210
|
-
let response = native ? await runNative({ ...args, native }) : await runOnce(args)
|
|
3241
|
+
let response = native ? await runNative({ ...args, native }) : await runOnce({ ...args, why: prepared.fallback || "retention capacity or reservation unavailable" })
|
|
3211
3242
|
const rebuild = async () => {
|
|
3212
|
-
const
|
|
3213
|
-
fallback
|
|
3243
|
+
const why = response.error?.continuityReason || "missing-batch-count"
|
|
3244
|
+
const fallback = await runOnce({ ...args, why })
|
|
3245
|
+
fallback.diagnostic = "stateless; bootstrap=imported-history; reason=" + why
|
|
3214
3246
|
return fallback
|
|
3215
3247
|
}
|
|
3216
3248
|
// A missing or conflicting native batch count may be retried once,
|
package/native-session.mjs
CHANGED
|
@@ -55,7 +55,13 @@ const failureOf = (e) => ({ status: e?.status ?? 502, message: e?.message ?? Str
|
|
|
55
55
|
|
|
56
56
|
// kindOf is what a frame of AgentServerMessage is, for Quiet: a heartbeat
|
|
57
57
|
// alone, or what an error names as the last thing Cursor sent
|
|
58
|
-
|
|
58
|
+
// (names after cursor-agent's agent.v1 InteractionUpdate, 2026.10.01)
|
|
59
|
+
const UPDATES = {
|
|
60
|
+
1: "text", 2: "tool call started", 3: "tool call completed", 4: "thinking", 5: "thinking done",
|
|
61
|
+
6: "user message", 7: "partial tool call", 8: "token count", 9: "summary", 10: "summary started",
|
|
62
|
+
11: "summary done", 12: "shell output", 14: "turn end", 15: "tool call delta", 16: "step started",
|
|
63
|
+
17: "step done", 27: "tool count",
|
|
64
|
+
}
|
|
59
65
|
const MESSAGES = { 2: "tool call", 3: "checkpoint", 4: "blob request" }
|
|
60
66
|
function kindOf(f) {
|
|
61
67
|
if (f.end) return "stream end"
|
|
@@ -249,6 +255,26 @@ export function scrub(s) {
|
|
|
249
255
|
.replace(/[A-Za-z0-9_\-+/=.]{24,}/g, "<redacted>")
|
|
250
256
|
.slice(0, 2000)
|
|
251
257
|
}
|
|
258
|
+
// detail is what a trace keeps of an inbound frame past its shape, all of
|
|
259
|
+
// it numbers of Cursor's protocol, never content (plugins#550): a tool
|
|
260
|
+
// count's number, the kind of call (ToolCall's field) a call update is
|
|
261
|
+
// of, and how many calls a checkpoint's state waits on
|
|
262
|
+
function detail(data) {
|
|
263
|
+
const out = {}
|
|
264
|
+
for (const m of nativeFields(data)) {
|
|
265
|
+
if (m.num === 1) {
|
|
266
|
+
for (const u of nativeFields(m.data)) {
|
|
267
|
+
if (u.num === 27) out.count = num(nativeFields(u.data), 1)
|
|
268
|
+
else if (u.num === 2 || u.num === 3 || u.num === 7) {
|
|
269
|
+
const tc = field(nativeFields(u.data), 2)
|
|
270
|
+
const kind = tc && nativeFields(tc.data)[0]
|
|
271
|
+
if (kind) out.tool = kind.wire === 2 ? [kind.num, nativeFields(kind.data)[0]?.num ?? 0] : [kind.num]
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
} else if (m.num === 3) out.pending = pendingCalls(m.data)
|
|
275
|
+
}
|
|
276
|
+
return out
|
|
277
|
+
}
|
|
252
278
|
export class WireTrace {
|
|
253
279
|
static open(meta) {
|
|
254
280
|
let dir = ""
|
|
@@ -258,6 +284,8 @@ export class WireTrace {
|
|
|
258
284
|
constructor(dir, meta = {}) {
|
|
259
285
|
this.dir = dir
|
|
260
286
|
this.meta = { path: String(meta.path ?? ""), model: String(meta.model ?? "") }
|
|
287
|
+
// why a Run went stateless: the retention fallback's reason
|
|
288
|
+
if (meta.why) this.meta.why = String(meta.why)
|
|
261
289
|
this.started = Date.now()
|
|
262
290
|
this.head = []
|
|
263
291
|
this.tail = []
|
|
@@ -281,6 +309,7 @@ export class WireTrace {
|
|
|
281
309
|
if (dir === "in") entry.kind = kind ?? "heartbeat"
|
|
282
310
|
if (dir === "in" && f.end) entry.end = true
|
|
283
311
|
else try { entry.fields = shape(data, true) } catch { entry.malformed = true }
|
|
312
|
+
if (dir === "in" && !f.end) try { Object.assign(entry, detail(data)) } catch {}
|
|
284
313
|
this.push(entry)
|
|
285
314
|
}
|
|
286
315
|
event(name, extra = {}) {
|
|
@@ -438,6 +467,67 @@ const field = (fs, n) => fs.find((f) => f.num === n)
|
|
|
438
467
|
const str = (fs, n) => field(fs, n)?.data.toString("utf8") ?? ""
|
|
439
468
|
const num = (fs, n) => field(fs, n)?.n ?? 0
|
|
440
469
|
|
|
470
|
+
// StepCalls is what Cursor says of a step's calls besides its execs
|
|
471
|
+
// (plugins#550). InteractionUpdate 2 (tool_call_started), 3
|
|
472
|
+
// (tool_call_completed) and 7 (partial_tool_call) each carry the call's
|
|
473
|
+
// call_id (field 1). A call Cursor completed by itself, never started on
|
|
474
|
+
// the client and never sent as an exec, is in tool_requests_listed's count
|
|
475
|
+
// all the same, and no exec of it will come: 0.2.34 waited for it while
|
|
476
|
+
// Cursor waited for the one call it had sent, 240 s, heartbeats only.
|
|
477
|
+
// parse is the path's field reader.
|
|
478
|
+
export class StepCalls {
|
|
479
|
+
constructor(parse) {
|
|
480
|
+
this.parse = parse
|
|
481
|
+
this.started = new Set()
|
|
482
|
+
this.execs = new Set() // the short strings of each exec's args: its tool_call_id among them
|
|
483
|
+
this.partial = new Set() // calls the model is writing in this step
|
|
484
|
+
this.byCursor = new Set()
|
|
485
|
+
}
|
|
486
|
+
// update takes an InteractionUpdate's own field (num) and its fields; it
|
|
487
|
+
// says whether a call was completed by Cursor: one this step wrote (7)
|
|
488
|
+
// and completed (3) with no start on the client (2) and no exec. A
|
|
489
|
+
// completion of an earlier step's call is never counted again.
|
|
490
|
+
update(n, uf) {
|
|
491
|
+
if (n !== 2 && n !== 3 && n !== 7) return false
|
|
492
|
+
const id = str(uf, 1)
|
|
493
|
+
if (!id) return false
|
|
494
|
+
if (n === 2) this.started.add(id)
|
|
495
|
+
if (n === 7) this.partial.add(id)
|
|
496
|
+
if (n !== 3) return false
|
|
497
|
+
if (!this.partial.has(id) || this.started.has(id) || this.execs.has(id) || this.byCursor.has(id)) return false
|
|
498
|
+
this.byCursor.add(id)
|
|
499
|
+
return true
|
|
500
|
+
}
|
|
501
|
+
// exec notes an exec's args, whatever its kind: each kind keeps its
|
|
502
|
+
// tool_call_id at a field of its own (ShellArgs 4, ReadArgs 2, McpArgs 3)
|
|
503
|
+
exec(data) {
|
|
504
|
+
try {
|
|
505
|
+
for (const e of this.parse(data)) {
|
|
506
|
+
if (e.wire !== 2 || e.num === 15 || e.num === 19) continue
|
|
507
|
+
for (const a of this.parse(e.data)) if (a.wire === 2 && a.data.length && a.data.length <= 512) this.execs.add(a.data.toString("utf8"))
|
|
508
|
+
}
|
|
509
|
+
} catch {}
|
|
510
|
+
}
|
|
511
|
+
get completed() {
|
|
512
|
+
return this.byCursor.size
|
|
513
|
+
}
|
|
514
|
+
// nextStep starts the next step's count
|
|
515
|
+
nextStep() {
|
|
516
|
+
this.partial.clear()
|
|
517
|
+
this.byCursor.clear()
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// pendingCalls is how many calls a checkpoint (ConversationStateStructure)
|
|
521
|
+
// says Cursor waits on: its pending_tool_calls, field 4; null when it
|
|
522
|
+
// can't be read
|
|
523
|
+
export function pendingCalls(data, parse = nativeFields) {
|
|
524
|
+
try {
|
|
525
|
+
return parse(data).filter((f) => f.num === 4).length
|
|
526
|
+
} catch {
|
|
527
|
+
return null
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
441
531
|
function argsOf(s) {
|
|
442
532
|
try {
|
|
443
533
|
const v = typeof s === "string" ? JSON.parse(s) : s
|
|
@@ -737,6 +827,8 @@ class NativeSession {
|
|
|
737
827
|
this.ac = new AbortController()
|
|
738
828
|
this.execs = new Map()
|
|
739
829
|
this.nativeCalls = new Map()
|
|
830
|
+
// what Cursor said of the step's calls besides its execs (plugins#550)
|
|
831
|
+
this.stepCalls = new StepCalls(nativeFields)
|
|
740
832
|
this.blobs = new Map()
|
|
741
833
|
this.knownHashes = new Set()
|
|
742
834
|
this.blobSize = 0
|
|
@@ -934,6 +1026,7 @@ class NativeSession {
|
|
|
934
1026
|
// caller's results, or after a step whose calls were all answered here.
|
|
935
1027
|
nextStep(estimate) {
|
|
936
1028
|
this.steps++
|
|
1029
|
+
this.stepCalls.nextStep()
|
|
937
1030
|
this.quiet.nextStep(this.steps)
|
|
938
1031
|
this.stepSaid = this.said
|
|
939
1032
|
if (estimate != null) this.stepEstimate = estimate
|
|
@@ -951,7 +1044,7 @@ class NativeSession {
|
|
|
951
1044
|
this.batchTimer = later(() => {
|
|
952
1045
|
const s = this.segment
|
|
953
1046
|
if (s.expected == null && s.calls.length && !this.resultSubmitted) this.missingCount()
|
|
954
|
-
else this.fail({ status: 502, message: `Cursor did not complete its declared native tool batch: ${s.calls.length} of ${s.expected ?? "?"} calls came, ${s.answered} answered here, none since ${Date.now() - since} ms` })
|
|
1047
|
+
else this.fail({ status: 502, message: `Cursor did not complete its declared native tool batch: ${s.calls.length} of ${s.expected ?? "?"} calls came, ${s.answered} answered here${this.stepCalls.completed ? `, ${this.stepCalls.completed} completed by Cursor` : ""}, none since ${Date.now() - since} ms` })
|
|
955
1048
|
}, this.limits.batchWait)
|
|
956
1049
|
}
|
|
957
1050
|
missingCount() {
|
|
@@ -967,6 +1060,23 @@ class NativeSession {
|
|
|
967
1060
|
if (this.batchTimer) this.waitForBatch()
|
|
968
1061
|
this.sealBatch()
|
|
969
1062
|
}
|
|
1063
|
+
// A call of the step Cursor completed by itself (plugins#550): in its
|
|
1064
|
+
// count, and never sent as an exec.
|
|
1065
|
+
completedByCursor() {
|
|
1066
|
+
if (this.terminal || this.state === "awaiting-results") return
|
|
1067
|
+
if (this.batchTimer) this.waitForBatch()
|
|
1068
|
+
this.sealBatch()
|
|
1069
|
+
}
|
|
1070
|
+
// A checkpoint whose state waits on just the calls handed to the caller,
|
|
1071
|
+
// after the step's count, is a step Cursor has finished: what more the
|
|
1072
|
+
// count says will not come (plugins#550).
|
|
1073
|
+
waitedOn(data) {
|
|
1074
|
+
const s = this.segment
|
|
1075
|
+
if (this.terminal || this.state === "awaiting-results" || s.closed || s.expected == null || !s.calls.length) return
|
|
1076
|
+
if (pendingCalls(data) !== s.calls.length) return
|
|
1077
|
+
s.waitedOn = true
|
|
1078
|
+
this.sealBatch()
|
|
1079
|
+
}
|
|
970
1080
|
listed(count) {
|
|
971
1081
|
if (!Number.isSafeInteger(count) || count < 1) invalid("invalid native tool count", 502)
|
|
972
1082
|
if (this.segment.expected != null && this.segment.expected !== count) {
|
|
@@ -986,7 +1096,8 @@ class NativeSession {
|
|
|
986
1096
|
if (segment.expected == null) return
|
|
987
1097
|
const made = segment.calls.length + segment.answered
|
|
988
1098
|
if (made > segment.expected) invalid("native tool batch exceeded its declared count", 502)
|
|
989
|
-
|
|
1099
|
+
// the calls Cursor completed by itself make up the rest (plugins#550)
|
|
1100
|
+
if ((made + this.stepCalls.completed < segment.expected && !segment.waitedOn) || segment.closed) return
|
|
990
1101
|
if (!segment.calls.length) {
|
|
991
1102
|
// Every call of the step was answered here: Cursor goes on with the
|
|
992
1103
|
// turn by itself, and its next step lists a count of its own.
|
|
@@ -1183,10 +1294,14 @@ class NativeSession {
|
|
|
1183
1294
|
if (this.error) return
|
|
1184
1295
|
} else if (u.num === 13) {
|
|
1185
1296
|
if (this.batchTimer && !this.terminal && this.state !== "awaiting-results") this.waitForBatch()
|
|
1297
|
+
} else if ((u.num === 2 || u.num === 3 || u.num === 7) && this.stepCalls.update(u.num, uf)) {
|
|
1298
|
+
this.completedByCursor()
|
|
1299
|
+
if (this.error) return
|
|
1186
1300
|
}
|
|
1187
1301
|
}
|
|
1188
1302
|
break
|
|
1189
1303
|
case 2: {
|
|
1304
|
+
this.stepCalls.exec(m.data)
|
|
1190
1305
|
const c = exec(m.data, this.chatTools, (b) => this.send(b), (id) => this.execClose(id), null, true)
|
|
1191
1306
|
if (c) this.acceptCall(c)
|
|
1192
1307
|
// request_context is Cursor asking for the environment, not a call
|
|
@@ -1195,6 +1310,7 @@ class NativeSession {
|
|
|
1195
1310
|
}
|
|
1196
1311
|
case 3:
|
|
1197
1312
|
this.checkpointReceived(m.data)
|
|
1313
|
+
this.waitedOn(m.data)
|
|
1198
1314
|
break
|
|
1199
1315
|
case 4: {
|
|
1200
1316
|
const kv = nativeFields(m.data)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magpie-community/opencode-cursor-auth",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.35",
|
|
4
4
|
"description": "Cursor subscriptions (Pro, Pro+, Ultra, Teams) in OpenCode and magpie, through the API cursor-agent talks to",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.mjs",
|