@magpie-community/opencode-cursor-auth 0.2.7 → 0.2.9
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/index.mjs +47 -8
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -723,17 +723,20 @@ function pick(entry, effort, fast, seed) {
|
|
|
723
723
|
// without thinking stops at high), the variant with those parameters at the
|
|
724
724
|
// nearest effort it has, not the default's id with parameters that
|
|
725
725
|
// contradict it (claude-opus-5-thinking-high with thinking=false). Where
|
|
726
|
-
// the default differs from what is asked in the effort alone,
|
|
727
|
-
// goes as asked, as for
|
|
726
|
+
// the default differs from what is asked in the effort alone, and no
|
|
727
|
+
// variant at all is named for that effort, the effort goes as asked, as for
|
|
728
|
+
// a listed model (claude-opus-5-5-xhigh). When another branch has it, the
|
|
729
|
+
// default's own branch stops short there, and its nearest goes (#55).
|
|
728
730
|
function branch(entry, want) {
|
|
729
731
|
if (!entry.pid || entry.pid === "thinking") return undefined
|
|
732
|
+
const level = (x) => (x === "extra-high" ? "xhigh" : x)
|
|
730
733
|
const def = valuesOf(entry.def)
|
|
731
|
-
|
|
734
|
+
const named = entry.variants.some((v) => level(valuesOf(v)[entry.pid]) === level(want[entry.pid]))
|
|
735
|
+
if (!named && Object.keys(want).every((k) => k === entry.pid || k === "context" || def[k] === undefined || def[k] === want[k])) return undefined
|
|
732
736
|
const vs = entry.variants.filter((v) => {
|
|
733
737
|
const have = valuesOf(v)
|
|
734
738
|
return entry.pid in have && Object.keys(want).every((k) => k === entry.pid || have[k] === undefined || have[k] === want[k])
|
|
735
739
|
})
|
|
736
|
-
const level = (x) => (x === "extra-high" ? "xhigh" : x)
|
|
737
740
|
const at = fitEffort(level(want[entry.pid]), vs.map((v) => level(valuesOf(v)[entry.pid])))
|
|
738
741
|
return at ? vs.find((v) => level(valuesOf(v)[entry.pid]) === at) : undefined
|
|
739
742
|
}
|
|
@@ -1896,6 +1899,12 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
1896
1899
|
let said = 0
|
|
1897
1900
|
// wrote: the reply's text alone; a turn of thinking only says nothing
|
|
1898
1901
|
let wrote = 0
|
|
1902
|
+
// what the Run sent, for an empty reply to name (#60): the thinking's
|
|
1903
|
+
// length, Cursor's own tools it asked for and was refused, and updates
|
|
1904
|
+
// and messages this doesn't read
|
|
1905
|
+
const seen = { thinking: 0, refused: new Map(), updates: new Map(), messages: new Map() }
|
|
1906
|
+
const count = (m, k) => m.set(k, (m.get(k) ?? 0) + 1)
|
|
1907
|
+
const empty = (how) => ({ error: { status: 502, message: "an empty reply" + emptyWhy(how, seen, ended ? usage : null) } })
|
|
1899
1908
|
let usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0 }
|
|
1900
1909
|
// counted: the step's usage is the dashboard's events, its own counted
|
|
1901
1910
|
// with it or by a later step (ledger), never guessed
|
|
@@ -1941,7 +1950,7 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
1941
1950
|
if (f.end) {
|
|
1942
1951
|
const e = failure(200, f.data)
|
|
1943
1952
|
if (e.status < 200 || e.status > 299) yield { error: e }
|
|
1944
|
-
else if (wrote === 0 && calls === 0) yield
|
|
1953
|
+
else if (wrote === 0 && calls === 0) yield empty(endFrame(f.data))
|
|
1945
1954
|
else yield await settled()
|
|
1946
1955
|
return
|
|
1947
1956
|
}
|
|
@@ -1966,6 +1975,7 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
1966
1975
|
const t = pbStr(uf, 1)
|
|
1967
1976
|
if (t) {
|
|
1968
1977
|
said += t.length
|
|
1978
|
+
seen.thinking += t.length
|
|
1969
1979
|
yield { reasoning: t }
|
|
1970
1980
|
}
|
|
1971
1981
|
break
|
|
@@ -1976,7 +1986,7 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
1976
1986
|
if (calls === 0) {
|
|
1977
1987
|
// nothing written and nothing called: an empty reply,
|
|
1978
1988
|
// which the client asks again, not a finished turn
|
|
1979
|
-
yield wrote === 0 ?
|
|
1989
|
+
yield wrote === 0 ? empty("Cursor ended the turn") : await settled()
|
|
1980
1990
|
return
|
|
1981
1991
|
}
|
|
1982
1992
|
break
|
|
@@ -1987,12 +1997,14 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
1987
1997
|
return
|
|
1988
1998
|
}
|
|
1989
1999
|
break
|
|
2000
|
+
default:
|
|
2001
|
+
count(seen.updates, u.num)
|
|
1990
2002
|
}
|
|
1991
2003
|
}
|
|
1992
2004
|
break
|
|
1993
2005
|
case 2: {
|
|
1994
2006
|
// exec_server_message: the server asks the client to run something
|
|
1995
|
-
const call = exec(m.data, tools, send, closeExec)
|
|
2007
|
+
const call = exec(m.data, tools, send, closeExec, seen.refused)
|
|
1996
2008
|
if (call) {
|
|
1997
2009
|
said += call.args.length
|
|
1998
2010
|
yield { tool: { index: calls++, ...call } }
|
|
@@ -2021,6 +2033,8 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
2021
2033
|
}
|
|
2022
2034
|
break
|
|
2023
2035
|
}
|
|
2036
|
+
default:
|
|
2037
|
+
count(seen.messages, m.num)
|
|
2024
2038
|
}
|
|
2025
2039
|
}
|
|
2026
2040
|
}
|
|
@@ -2038,10 +2052,33 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
2038
2052
|
}
|
|
2039
2053
|
}
|
|
2040
2054
|
|
|
2055
|
+
// endFrame is how a Run's Connect end frame that said no error reads in
|
|
2056
|
+
// an empty reply's words: its JSON, cut short, or that it was empty.
|
|
2057
|
+
function endFrame(data) {
|
|
2058
|
+
const t = Buffer.from(data ?? []).toString("utf8").trim()
|
|
2059
|
+
if (!t || t === "{}") return "the Run's stream ended (an empty end frame)"
|
|
2060
|
+
return `the Run's stream ended (end frame: ${t.length > 300 ? t.slice(0, 300) + "…" : t})`
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// emptyWhy is what an empty reply says of what came before it (#60): how
|
|
2064
|
+
// it ended, the thinking, the turn's own count of output, Cursor's own
|
|
2065
|
+
// tools refused, and what Cursor sent that isn't read. Field numbers are
|
|
2066
|
+
// agent.v1's, so a report names the message that wasn't understood.
|
|
2067
|
+
function emptyWhy(how, seen, usage) {
|
|
2068
|
+
const list = (m) => [...m].map(([k, n]) => (n > 1 ? `#${k} ×${n}` : `#${k}`)).join(", ")
|
|
2069
|
+
const parts = [how]
|
|
2070
|
+
parts.push(seen.thinking ? `after ${seen.thinking} chars of thinking, no text and no tool call` : "with no thinking, no text and no tool call")
|
|
2071
|
+
if (usage) parts.push(`Cursor counted ${usage.output} output tokens`)
|
|
2072
|
+
if (seen.refused.size) parts.push(`Cursor's own tools asked for and refused: ${list(seen.refused)}`)
|
|
2073
|
+
if (seen.updates.size) parts.push(`updates not read: ${list(seen.updates)}`)
|
|
2074
|
+
if (seen.messages.size) parts.push(`messages not read: ${list(seen.messages)}`)
|
|
2075
|
+
return ` (${parts.join("; ")}; try again)`
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2041
2078
|
// exec answers what the server asks the client to run: a call of the
|
|
2042
2079
|
// caller's tools is returned, the list of them is given, and anything else
|
|
2043
2080
|
// is refused.
|
|
2044
|
-
function exec(msg, tools, send, closeExec) {
|
|
2081
|
+
function exec(msg, tools, send, closeExec, refused) {
|
|
2045
2082
|
const es = fields(msg)
|
|
2046
2083
|
const id = pbNum(es, 1)
|
|
2047
2084
|
const execID = pbStr(es, 15)
|
|
@@ -2080,6 +2117,8 @@ function exec(msg, tools, send, closeExec) {
|
|
|
2080
2117
|
}
|
|
2081
2118
|
}
|
|
2082
2119
|
// a shell, a file read or an edit of Cursor's own: never run
|
|
2120
|
+
const kind = es.find((e) => e.num !== 1 && e.num !== 15)?.num ?? 0
|
|
2121
|
+
refused?.set(kind, (refused.get(kind) ?? 0) + 1)
|
|
2083
2122
|
send(pb().bytes(5, pb().bytes(2, pb().varint(1, id).str(2, "not available"))).done())
|
|
2084
2123
|
closeExec(id)
|
|
2085
2124
|
return null
|
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.9",
|
|
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",
|