cartethyia 2.5.8 → 2.5.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.
Files changed (73) hide show
  1. package/dist/dashboard/assets/{BannedPage-BKAI54IA.js → BannedPage-Brvuj_Eb.js} +1 -1
  2. package/dist/dashboard/assets/BannedPage-Brvuj_Eb.js.gz +0 -0
  3. package/dist/dashboard/assets/{CliToolDetailPage-CkGvxrHu.js → CliToolDetailPage-CqfXtI3y.js} +1 -1
  4. package/dist/dashboard/assets/CliToolDetailPage-CqfXtI3y.js.gz +0 -0
  5. package/dist/dashboard/assets/{CliToolsPage-Cj8MYpeY.js → CliToolsPage-GQeS91bg.js} +1 -1
  6. package/dist/dashboard/assets/CliToolsPage-GQeS91bg.js.gz +0 -0
  7. package/dist/dashboard/assets/{CombosPage-BDXBEbWT.js → CombosPage-BDRsTXBB.js} +1 -1
  8. package/dist/dashboard/assets/CombosPage-BDRsTXBB.js.gz +0 -0
  9. package/dist/dashboard/assets/{ConsoleLogPage-49KH4z3l.js → ConsoleLogPage-zP8AFHX0.js} +1 -1
  10. package/dist/dashboard/assets/ConsoleLogPage-zP8AFHX0.js.gz +0 -0
  11. package/dist/dashboard/assets/{CustomizationPage-EHjBmNBZ.js → CustomizationPage-BmfrNZ14.js} +1 -1
  12. package/dist/dashboard/assets/CustomizationPage-BmfrNZ14.js.gz +0 -0
  13. package/dist/dashboard/assets/{HealthEventsModal-ByUTtj7j.js → HealthEventsModal-Dn3M6WZc.js} +1 -1
  14. package/dist/dashboard/assets/HealthEventsModal-Dn3M6WZc.js.gz +0 -0
  15. package/dist/dashboard/assets/{LoginPage-CYSCKT8S.js → LoginPage-DoreIgm8.js} +1 -1
  16. package/dist/dashboard/assets/LoginPage-DoreIgm8.js.gz +0 -0
  17. package/dist/dashboard/assets/{OverviewPage-Bu3iqBMm.js → OverviewPage-CvvD1Ugk.js} +1 -1
  18. package/dist/dashboard/assets/OverviewPage-CvvD1Ugk.js.gz +0 -0
  19. package/dist/dashboard/assets/{ProviderDetailPage-FHdgmgjU.js → ProviderDetailPage-Clbn1gsW.js} +1 -1
  20. package/dist/dashboard/assets/ProviderDetailPage-Clbn1gsW.js.gz +0 -0
  21. package/dist/dashboard/assets/{ProvidersPage-CCvYS9CF.js → ProvidersPage-BnoPgA7w.js} +1 -1
  22. package/dist/dashboard/assets/ProvidersPage-BnoPgA7w.js.gz +0 -0
  23. package/dist/dashboard/assets/{ProxyPage-HOl9cjxl.js → ProxyPage-Bq_TGgdb.js} +1 -1
  24. package/dist/dashboard/assets/ProxyPage-Bq_TGgdb.js.gz +0 -0
  25. package/dist/dashboard/assets/{QuotaPage-MUGzIpTK.js → QuotaPage-D9DHXvom.js} +1 -1
  26. package/dist/dashboard/assets/QuotaPage-D9DHXvom.js.gz +0 -0
  27. package/dist/dashboard/assets/{SettingsPage-CTdF5TCa.js → SettingsPage-7xV8WkWL.js} +1 -1
  28. package/dist/dashboard/assets/SettingsPage-7xV8WkWL.js.gz +0 -0
  29. package/dist/dashboard/assets/{SetupPage-Bra7rkKx.js → SetupPage-Day3mCOn.js} +1 -1
  30. package/dist/dashboard/assets/SetupPage-Day3mCOn.js.gz +0 -0
  31. package/dist/dashboard/assets/{SortableList-BRscd-vl.js → SortableList-DQxllnB5.js} +1 -1
  32. package/dist/dashboard/assets/SortableList-DQxllnB5.js.gz +0 -0
  33. package/dist/dashboard/assets/{StudioPage-BeevnFtM.js → StudioPage-uMExoWu1.js} +1 -1
  34. package/dist/dashboard/assets/StudioPage-uMExoWu1.js.gz +0 -0
  35. package/dist/dashboard/assets/{UsagePage-BWik9fpu.js → UsagePage-DXa1oR-4.js} +1 -1
  36. package/dist/dashboard/assets/UsagePage-DXa1oR-4.js.gz +0 -0
  37. package/dist/dashboard/assets/{entry-BqZ5vrM7.js → entry-ByMGkR3C.js} +3 -3
  38. package/dist/dashboard/assets/entry-ByMGkR3C.js.gz +0 -0
  39. package/dist/dashboard/assets/{index-9ARd3FIs.js → index-z3zDOSMM.js} +2 -2
  40. package/dist/dashboard/assets/index-z3zDOSMM.js.gz +0 -0
  41. package/dist/dashboard/assets/{select-D_BBhBEF.js → select-C6MMiaio.js} +1 -1
  42. package/dist/dashboard/assets/select-C6MMiaio.js.gz +0 -0
  43. package/dist/dashboard/index.html +1 -1
  44. package/dist/dashboard/index.html.gz +0 -0
  45. package/dist/dashboard/precompressed-assets.json +21 -21
  46. package/package.json +1 -1
  47. package/src/console/backup/nine-router.ts +43 -9
  48. package/src/providers/discovery/openrouter-free-roster.ts +0 -1
  49. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +3 -2
  50. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +2 -1
  51. package/src/providers/integrations/opencode/provider.ts +0 -3
  52. package/src/providers/operations/provider-credential-service.ts +29 -3
  53. package/dist/dashboard/assets/BannedPage-BKAI54IA.js.gz +0 -0
  54. package/dist/dashboard/assets/CliToolDetailPage-CkGvxrHu.js.gz +0 -0
  55. package/dist/dashboard/assets/CliToolsPage-Cj8MYpeY.js.gz +0 -0
  56. package/dist/dashboard/assets/CombosPage-BDXBEbWT.js.gz +0 -0
  57. package/dist/dashboard/assets/ConsoleLogPage-49KH4z3l.js.gz +0 -0
  58. package/dist/dashboard/assets/CustomizationPage-EHjBmNBZ.js.gz +0 -0
  59. package/dist/dashboard/assets/HealthEventsModal-ByUTtj7j.js.gz +0 -0
  60. package/dist/dashboard/assets/LoginPage-CYSCKT8S.js.gz +0 -0
  61. package/dist/dashboard/assets/OverviewPage-Bu3iqBMm.js.gz +0 -0
  62. package/dist/dashboard/assets/ProviderDetailPage-FHdgmgjU.js.gz +0 -0
  63. package/dist/dashboard/assets/ProvidersPage-CCvYS9CF.js.gz +0 -0
  64. package/dist/dashboard/assets/ProxyPage-HOl9cjxl.js.gz +0 -0
  65. package/dist/dashboard/assets/QuotaPage-MUGzIpTK.js.gz +0 -0
  66. package/dist/dashboard/assets/SettingsPage-CTdF5TCa.js.gz +0 -0
  67. package/dist/dashboard/assets/SetupPage-Bra7rkKx.js.gz +0 -0
  68. package/dist/dashboard/assets/SortableList-BRscd-vl.js.gz +0 -0
  69. package/dist/dashboard/assets/StudioPage-BeevnFtM.js.gz +0 -0
  70. package/dist/dashboard/assets/UsagePage-BWik9fpu.js.gz +0 -0
  71. package/dist/dashboard/assets/entry-BqZ5vrM7.js.gz +0 -0
  72. package/dist/dashboard/assets/index-9ARd3FIs.js.gz +0 -0
  73. package/dist/dashboard/assets/select-D_BBhBEF.js.gz +0 -0
@@ -152,14 +152,33 @@ export async function loadAccountWithFreshness(
152
152
  const row = rows[0];
153
153
  if (!row) return undefined;
154
154
  const lead = skewMs ?? refreshLeadMs(row.providerId);
155
+ // A refresh-capable OAuth account with no stored expiry is unknown-liveness:
156
+ // we have no evidence the access token still works. The old rule left
157
+ // `dueAt` undefined for these, so `resolveCredentialForAccount` skipped the
158
+ // refresh branch and dispatch sent the pasted token as-is. For a token that
159
+ // had already expired on another installation (a 9router/Omniroute import
160
+ // carrying `accessToken` + `refreshToken` + a past `expiresAt` that was
161
+ // dropped by validation, a hand-pasted OAuth bundle with no expiry field,
162
+ // or an upstream that stopped minting expiries) that produced the exact
163
+ // "re-authenticate" refusal the refresh grant exists to prevent. Marking the
164
+ // token due immediately refreshes it on first use; the sweep handles the
165
+ // normal case where `expires_at` is populated.
166
+ const hasRefreshGrant = row.refreshCiphertext != null;
167
+ const kindOauth = row.credentialKind === "oauth";
168
+ const unknownExpiryButRefreshable =
169
+ kindOauth && !row.staticToken && hasRefreshGrant && row.expiresAt == null;
155
170
  return {
156
171
  row,
157
172
  // A static token is never "due": it is used as issued and there is no
158
173
  // refresh to run, so the dispatch path must not treat it as stale.
159
174
  dueAt:
160
- row.staticToken || row.expiresAt == null
175
+ row.staticToken
161
176
  ? undefined
162
- : row.expiresAt.getTime() - lead,
177
+ : row.expiresAt != null
178
+ ? row.expiresAt.getTime() - lead
179
+ : unknownExpiryButRefreshable
180
+ ? 0
181
+ : undefined,
163
182
  };
164
183
  }
165
184
 
@@ -223,7 +242,14 @@ export async function resolveCredentialForAccount(
223
242
  if (row.credentialKind === "oauth" && oauth && dueAt !== undefined && dueAt <= Date.now()) {
224
243
  const refresher = await oauth.resolveRefresher(row.providerId);
225
244
  if (refresher) {
226
- secret = await oauth.refreshService.ensureFreshAccessToken(accountId, refresher) ?? undefined;
245
+ // Try to refresh. If it fails (refresh grant dead, upstream unreachable,
246
+ // etc.) keep the already-decrypted stale secret rather than wiping it:
247
+ // dispatch then sends the token we have, and the upstream's own 401 is
248
+ // the authoritative verdict. Wiping it here turned "token expired" into
249
+ // a credential-less GatewayError before the request ever left, which is
250
+ // worse than letting the server say so.
251
+ const refreshed = await oauth.refreshService.ensureFreshAccessToken(accountId, refresher);
252
+ if (refreshed) secret = refreshed;
227
253
  }
228
254
  }
229
255