@magpie-community/opencode-workbuddy-auth 0.1.33 → 0.1.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.
Files changed (2) hide show
  1. package/index.mjs +29 -5
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -1598,9 +1598,11 @@ const compact = (n) => (Number.isInteger(n) ? String(n) : n.toFixed(2).replace(/
1598
1598
  // usageOf is the account's credits, from its resource summary: the plan's
1599
1599
  // credits used against what the cycle grants, as magpie's built-in said —
1600
1600
  // the count itself too (amount of limit, in credits), for magpie to say it
1601
- // as used or left beside the share (magpie#659).
1601
+ // as used or left beside the share (magpie#659). The free plan is said as a
1602
+ // plan: "Free" alone beside the account read as the model being free, and
1603
+ // routing as preferring it for that (#337).
1602
1604
  function usageOf(sum, plan) {
1603
- const out = { plan: plan || (sum?.IsPaidUser ? "Pro" : "Free"), windows: [] }
1605
+ const out = { plan: plan || (sum?.IsPaidUser ? "Pro" : "Free plan"), windows: [] }
1604
1606
  let total = 0, used = 0
1605
1607
  for (const p of sum?.Packages ?? []) {
1606
1608
  total += capacity(p?.CycleTotalCapacity)
@@ -1717,6 +1719,26 @@ function runsOutOf(sum, packages, now = Date.now()) {
1717
1719
  return at ? { runsOutAt: new Date(at).toISOString(), runsOut: amount } : null
1718
1720
  }
1719
1721
 
1722
+ // cycleOf is when the plan's credits start again, as WorkBuddy's own client
1723
+ // says it (getCurrentPlan's refreshAt): the cycle end of the package the
1724
+ // summary names as the subscription (SubscriptionPackageCode), in UTC+8,
1725
+ // with how long the cycle is. Without it the card had used credits and no
1726
+ // reset, and magpie said "Not used yet" beside 46% (windy on Discord,
1727
+ // 2026-10-26). null when the subscription isn't in the lists, or its cycle
1728
+ // is over.
1729
+ function cycleOf(sum, packages, now = Date.now()) {
1730
+ const code = sum?.SubscriptionPackageCode
1731
+ if (!code) return null
1732
+ const at = (v) => (typeof v === "string" && /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(v.trim()) ? Date.parse(v.trim().replace(" ", "T") + "+08:00") : 0)
1733
+ for (const p of packages ?? []) {
1734
+ if (p?.PackageCode !== code) continue
1735
+ const end = at(p?.CycleEndTime), start = at(p?.CycleStartTime)
1736
+ if (!(end > now)) continue
1737
+ return { resetsAt: new Date(end).toISOString(), ...(start > 0 && start < end ? { span: (end - start) / 1000 } : {}) }
1738
+ }
1739
+ return null
1740
+ }
1741
+
1720
1742
  // ---- models -----------------------------------------------------------------
1721
1743
 
1722
1744
  // variants are the reasoning levels as OpenCode gives them to the AI SDK.
@@ -2157,12 +2179,14 @@ function makePlugin(site) {
2157
2179
  } catch {}
2158
2180
  if (ent) return { plan: auth.plan || "Enterprise", windows: await spareFree(site, a, [ent]), signIn: said }
2159
2181
  }
2160
- // when the credits left run out, for routing to spend them first;
2182
+ // when the plan's credits start again (cycleOf), and when the credits
2183
+ // left run out, for routing to spend them first (runsOutOf);
2161
2184
  // a list that can't be read leaves it unknown, the card stands
2162
2185
  const credits = out.windows.find((w) => w.name === "Credits")
2163
2186
  if (credits) {
2164
2187
  try {
2165
- Object.assign(credits, runsOutOf(sum, await packagesOf(site, a)) ?? {})
2188
+ const packages = await packagesOf(site, a)
2189
+ Object.assign(credits, cycleOf(sum, packages) ?? {}, runsOutOf(sum, packages) ?? {})
2166
2190
  } catch {}
2167
2191
  }
2168
2192
  await spareFree(site, a, out.windows)
@@ -2289,4 +2313,4 @@ export const WorkBuddyAuthPlugin = makePlugin(SITES.workbuddy)
2289
2313
  export const WorkBuddyAIAuthPlugin = makePlugin(SITES["workbuddy-ai"])
2290
2314
 
2291
2315
  // for tests
2292
- export const _internal = { typeUnions, systemAsUser, systemKey, DEFAULT_SYSTEM, EDGE_READS, fitShape, replyAfterTools, AFTER_TOOLS_REFUSED, enterpriseUsageOf, notDesktop, textOnly, runsOutOf, packagesOf, endOf, enterpriseHeaders, enterpriseOf, liveModels, browserSignIn, withSystem, normalizeToolChoice, fitTools, fitted, renamed, unflagged, usageOf, desktopHeld, explained, REFUSED_HINT, RESTRICTED_HINT, EXHAUSTED_HINT, freeCredits, creditsOf, priceOf, fresh, SITES, renewing, renewed, SESSION, attend, turnKey, conversationKey, signatureOf, isMessages, withoutUnsigned, withoutSignedThinking, answeredBefore, nativeOf, modelOf, configModels, API_MESSAGES: NPM_MESSAGES, API_CHAT: NPM }
2316
+ export const _internal = { cycleOf, typeUnions, systemAsUser, systemKey, DEFAULT_SYSTEM, EDGE_READS, fitShape, replyAfterTools, AFTER_TOOLS_REFUSED, enterpriseUsageOf, notDesktop, textOnly, runsOutOf, packagesOf, endOf, enterpriseHeaders, enterpriseOf, liveModels, browserSignIn, withSystem, normalizeToolChoice, fitTools, fitted, renamed, unflagged, usageOf, desktopHeld, explained, REFUSED_HINT, RESTRICTED_HINT, EXHAUSTED_HINT, freeCredits, creditsOf, priceOf, fresh, SITES, renewing, renewed, SESSION, attend, turnKey, conversationKey, signatureOf, isMessages, withoutUnsigned, withoutSignedThinking, answeredBefore, nativeOf, modelOf, configModels, API_MESSAGES: NPM_MESSAGES, API_CHAT: NPM }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-workbuddy-auth",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "OpenCode provider plugins for WorkBuddy's plans: WorkBuddy (CodeBuddy, copilot.tencent.com) and WorkBuddy AI (www.workbuddy.ai)",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",