@magpie-community/opencode-cursor-auth 0.2.24 → 0.2.25

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.
Files changed (3) hide show
  1. package/README.md +8 -1
  2. package/index.mjs +40 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -203,7 +203,14 @@ minutes), the way pi-cursor-sdk lists Cursor's catalog:
203
203
  (`claude-opus-5-5`), its efforts as variants, and goes as the usable id
204
204
  those parameters pick, never as the family id Cursor doesn't know. A
205
205
  picker model whose chosen variant isn't one the account can use goes as
206
- its family's nearest usable id the same way.
206
+ its family's nearest usable id the same way. Such a family is named
207
+ without the tier Cursor's names carry ("Claude Opus 5 1M Medium
208
+ Thinking" is listed as Claude Opus 5 Thinking): the tier is the
209
+ reasoning level the agent asks for (low to max, as the account has
210
+ them), fast the request's `service_tier`.
211
+ - An id for a model with thinking that the account lists only without it
212
+ (`claude-haiku-5-5-thinking` when the list has Claude Haiku 5.5 alone),
213
+ or the other way round, runs as the model the account has.
207
214
  - An `@<size>` id the list no longer has (`claude-opus-5-5@1m` when only
208
215
  300k is listed, or the model is listed unsized) runs at the model's
209
216
  nearest size, in Max Mode when the size asked for is over the model's
package/index.mjs CHANGED
@@ -773,14 +773,31 @@ function fromUsable(fam, effort, fast) {
773
773
  return (at && vs.find((u) => u.effort === at)) || vs.find((u) => u.effort === "") || vs.find((u) => u.effort === "medium") || vs[0]
774
774
  }
775
775
 
776
- // usableTitle is a usable id's name without what the id says apart: the
776
+ // usableTitle is a usable id's name without what the id says apart: its
777
777
  // effort, fast, and the 1M Cursor names every Max-capable Claude with
778
- // ("Claude Opus 5.5 1M Low" is Claude Opus 5.5).
779
- function usableTitle(name) {
780
- const drop = new Set(["low", "medium", "high", "xhigh", "extra", "max", "minimal", "none", "fast", "1m", "(1m)"])
781
- const ws = name.split(" ")
782
- while (ws.length > 1 && drop.has(ws.at(-1).toLowerCase())) ws.pop()
783
- return ws.join(" ")
778
+ // ("Claude Opus 5.5 1M Low" is Claude Opus 5.5), wherever Cursor puts
779
+ // them: "Claude Opus 5 1M Medium Thinking" is Claude Opus 5 Thinking, as
780
+ // its efforts are magpie's reasoning levels and not models of their own
781
+ // (ysm119 on Discord read "Medium" in the name as the only tier). A word
782
+ // of the model's own name stays: GPT-5.1 Codex Max at high is "GPT-5.1
783
+ // Codex Max".
784
+ const EFFORT_WORDS = { none: ["None"], minimal: ["Minimal"], low: ["Low"], medium: ["Medium"], high: ["High"], xhigh: ["Extra High", "XHigh"], max: ["Max"] }
785
+ function usableTitle(u) {
786
+ const ws = u.name.split(" ")
787
+ // the last time a phrase is said, past the name's first word
788
+ const cutLast = (phrase) => {
789
+ const p = phrase.toLowerCase().split(" ")
790
+ for (let i = ws.length - p.length; i >= 1; i--) {
791
+ if (p.every((w, k) => ws[i + k].toLowerCase() === w)) {
792
+ ws.splice(i, p.length)
793
+ return true
794
+ }
795
+ }
796
+ return false
797
+ }
798
+ for (const p of EFFORT_WORDS[u.effort] ?? []) if (cutLast(p)) break
799
+ if (u.fast) cutLast("fast")
800
+ return ws.filter((w, i) => i === 0 || !/^\(?1m\)?$/i.test(w)).join(" ") || u.name
784
801
  }
785
802
 
786
803
  // modelsOf is the picker's models as offered: one entry for each context
@@ -833,7 +850,7 @@ function modelsOf(picker, ids, listed = []) {
833
850
  const def = fromUsable(fam, "", false)
834
851
  // Cursor's context for it isn't known: its default's, as for a model
835
852
  // the picker gives no limit for
836
- out.push({ id: family, run: family, name: usableTitle(def.name), title: usableTitle(def.name), pid: "", levels, fast: false, variants: [], def: undefined, partial: false, model: { name: family }, fam, ids, usableOnly: true, context: DEFAULT_CONTEXT, size: "", offersFast: fam.some((u) => u.fast) })
853
+ out.push({ id: family, run: family, name: usableTitle(def), title: usableTitle(def), pid: "", levels, fast: false, variants: [], def: undefined, partial: false, model: { name: family }, fam, ids, usableOnly: true, context: DEFAULT_CONTEXT, size: "", offersFast: fam.some((u) => u.fast) })
837
854
  }
838
855
  return out
839
856
  }
@@ -1014,6 +1031,21 @@ function named(raw, id) {
1014
1031
  if (u) return { entry: e, seed: undefined, effort: u.effort, fast: u.fast }
1015
1032
  if (e.id === of.family) return { entry: e, seed: undefined, effort: of.effort, fast: of.fast }
1016
1033
  }
1034
+ // a family neither has, where the account has the same model with
1035
+ // thinking or without it (claude-haiku-5-5-thinking, which 0.1.x listed,
1036
+ // on a Team account whose list has Claude Haiku 5.5 without a thinking
1037
+ // id; ysm119 on Discord): that one, at the id's effort, never the id as
1038
+ // it is, which Cursor answers "AI Model Not Found"
1039
+ const loose = (f) => f.replace(/-thinking$/, "")
1040
+ const key = loose(of.family)
1041
+ for (const e of models) {
1042
+ if (e.usableOnly) {
1043
+ if (loose(e.id) === key) return { entry: e, seed: undefined, effort: of.effort, fast: of.fast }
1044
+ continue
1045
+ }
1046
+ const vs = e.variants.filter((v) => v.legacySlug && loose(familyOf(v.legacySlug).family) === key)
1047
+ if (vs.length) return as(e, vs, of.effort)
1048
+ }
1017
1049
  // an id at a context size the list no longer has (claude-opus-5-5@1m,
1018
1050
  // picked from an earlier list, or from another account's): the model at
1019
1051
  // the nearest size it has; a model listed without sizes, in Max Mode for
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-cursor-auth",
3
- "version": "0.2.24",
3
+ "version": "0.2.25",
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",