antigravity-claude-proxy 3.0.0 → 3.1.0

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 (53) hide show
  1. package/bin/cli.js +4 -11
  2. package/package.json +1 -1
  3. package/public/app.js +7 -4
  4. package/public/css/src/input.css +379 -216
  5. package/public/css/style.css +1 -1
  6. package/public/favicon.svg +4 -8
  7. package/public/index.html +78 -72
  8. package/public/js/components/claude-config.js +0 -8
  9. package/public/js/components/dashboard/charts.js +25 -51
  10. package/public/js/components/dashboard/stats.js +1 -1
  11. package/public/js/components/dashboard.js +16 -21
  12. package/public/js/components/logs-viewer.js +1 -1
  13. package/public/js/components/models.js +12 -12
  14. package/public/js/components/server-config.js +1 -9
  15. package/public/js/data-store.js +2 -2
  16. package/public/js/store.js +1 -1
  17. package/public/js/translations/en.js +37 -39
  18. package/public/js/translations/id.js +36 -37
  19. package/public/js/translations/pt.js +37 -38
  20. package/public/js/translations/tr.js +37 -39
  21. package/public/js/translations/zh.js +0 -2
  22. package/public/js/utils/error-handler.js +0 -2
  23. package/public/js/utils/ui-logger.js +4 -3
  24. package/public/views/accounts.html +34 -38
  25. package/public/views/dashboard.html +86 -99
  26. package/public/views/logs.html +4 -4
  27. package/public/views/models.html +32 -36
  28. package/public/views/settings.html +50 -50
  29. package/src/account-manager/index.js +0 -4
  30. package/src/account-manager/rate-limits.js +0 -5
  31. package/src/account-manager/strategies/base-strategy.js +4 -4
  32. package/src/account-manager/strategies/hybrid-strategy.js +3 -3
  33. package/src/auth/database.js +1 -0
  34. package/src/auth/oauth.js +43 -41
  35. package/src/auth/token-extractor.js +1 -1
  36. package/src/cli/accounts.js +2 -1
  37. package/src/cloudcode/model-registry.js +0 -3
  38. package/src/cloudcode/rate-limit-state.js +1 -7
  39. package/src/config.js +1 -1
  40. package/src/constants.js +0 -2
  41. package/src/format/content-converter.js +0 -4
  42. package/src/format/request-converter.js +1 -6
  43. package/src/format/response-converter.js +0 -3
  44. package/src/format/schema-sanitizer.js +3 -22
  45. package/src/format/thinking-utils.js +1 -13
  46. package/src/index.js +1 -6
  47. package/src/modules/usage-stats.js +1 -1
  48. package/src/server.js +1 -28
  49. package/src/utils/claude-config.js +2 -6
  50. package/src/utils/native-module-helper.js +0 -4
  51. package/src/utils/proxy.js +1 -10
  52. package/src/utils/version-detector.js +14 -5
  53. package/src/webui/index.js +1 -37
@@ -8,23 +8,23 @@ window.translations.tr = {
8
8
  accounts: "Hesaplar",
9
9
  logs: "Günlükler",
10
10
  settings: "Ayarlar",
11
- online: "ÇEVRİMİÇİ",
12
- offline: "ÇEVRİMDIŞI",
13
- totalAccounts: "TOPLAM HESAP",
14
- active: "AKTİF",
11
+ online: "Çevrimiçi",
12
+ offline: "Çevrimdışı",
13
+ totalAccounts: "Toplam hesap",
14
+ active: "Aktif",
15
15
  operational: "Çalışıyor",
16
- rateLimited: "HIZ SINIRLANDI",
16
+ rateLimited: "Hız sınırlandı",
17
17
  quotasDepleted: "{count}/{total} Kota Tükendi",
18
- quotasDepletedTitle: "KOTA TÜKENDİ",
18
+ quotasDepletedTitle: "Kota tükendi",
19
19
  outOfTracked: "{total} Takip Edilen İçinden",
20
20
  cooldown: "Soğuma",
21
21
  searchPlaceholder: "Modelleri ara...",
22
22
  allAccounts: "Tüm Hesaplar",
23
- stat: "DURUM",
24
- modelIdentity: "MODEL KİMLİĞİ",
25
- globalQuota: "GENEL KOTA",
26
- nextReset: "SONRAKİ SIFIRLAMA",
27
- distribution: "HESAP DAĞILIMI",
23
+ stat: "Durum",
24
+ modelIdentity: "Model kimliği",
25
+ globalQuota: "Genel kota",
26
+ nextReset: "Sonraki sıfırlama",
27
+ distribution: "Hesap dağılımı",
28
28
  systemConfig: "Sistem Yapılandırması",
29
29
  language: "Dil",
30
30
  pollingInterval: "Veri Güncelleme Aralığı",
@@ -41,14 +41,14 @@ window.translations.tr = {
41
41
  accountManagement: "Hesap Yönetimi",
42
42
  manageTokens: "Google Hesap jetonlarını ve yetkilendirme durumlarını yönet",
43
43
  addAccount: "Hesap Ekle",
44
- status: "DURUM",
45
- enabled: "ETKİN",
46
- health: "SAĞLIK",
47
- accountEmail: "HESAP (E-POSTA)",
48
- source: "KAYNAK",
49
- projectId: "PROJE ID",
50
- sessionState: "OTURUM DURUMU",
51
- operations: "İŞLEMLER",
44
+ status: "Durum",
45
+ enabled: "Etkin",
46
+ health: "Sağlık",
47
+ accountEmail: "Hesap (e-posta)",
48
+ source: "Kaynak",
49
+ projectId: "Proje ID",
50
+ sessionState: "Oturum durumu",
51
+ operations: "İşlemler",
52
52
  delete: "Sil",
53
53
  confirmDelete: "Bu hesabı kaldırmak istediğinizden emin misiniz?",
54
54
  cannotDeleteDatabase: "Silinemez: Bu hesap Antigravity veritabanından (salt okunur)",
@@ -72,8 +72,8 @@ window.translations.tr = {
72
72
  tabServer: "Sunucu Ayarları",
73
73
  // Dashboard
74
74
  linkedAccounts: "Bağlı Hesaplar",
75
- noSignal: "SİNYAL YOK",
76
- establishingUplink: "BAĞLANTI KURULUYOR...",
75
+ noSignal: "Sinyal yok",
76
+ establishingUplink: "Bağlantı kuruluyor...",
77
77
  goToAccounts: "Hesaplara Git",
78
78
  // Settings - Models
79
79
  modelsDesc: "Model görünürlüğünü, sabitlemeyi ve istek yönlendirmeyi yapılandırın.",
@@ -86,13 +86,12 @@ window.translations.tr = {
86
86
  actions: "İşlemler",
87
87
  pinToTop: "En Üste Sabitle",
88
88
  toggleVisibility: "Görünürlüğü Değiştir",
89
- noModels: "MODEL ALGILANMADI",
89
+ noModels: "Model algılanmadı",
90
90
  modelMappingHint: "Sunucu tarafı model yönlendirme. Claude Code kullanıcıları: istemci tarafı kurulumu için 'Claude CLI' sekmesine bakın.",
91
- modelMapping: "Eşleştirme (Hedef Model ID)",
92
91
  // Settings - Claude
93
92
  proxyConnection: "Proxy Bağlantısı",
94
93
  modelSelection: "Model Seçimi",
95
- defaultModelAliases: "VARSAYILAN MODEL TAKMA ADLARI",
94
+ defaultModelAliases: "Varsayılan model takma adları",
96
95
  opusAlias: "Opus Takma Adı",
97
96
  sonnetAlias: "Sonnet Takma Adı",
98
97
  haikuAlias: "Haiku Takma Adı",
@@ -150,20 +149,19 @@ window.translations.tr = {
150
149
  saveConfig: "Claude CLI ayarlarına kaydet",
151
150
  envVar: "Ortam Değişkeni",
152
151
  // New Keys
153
- systemName: "ANTIGRAVITY",
154
- systemDesc: "CLAUDE PROXY SİSTEMİ",
152
+ systemName: "Antigravity",
153
+ systemDesc: "Claude proxy sistemi",
155
154
  connectGoogleDesc: "API kota limitinizi artırmak için bir Google Workspace hesabı bağlayın. Bu hesap, Claude isteklerini Antigravity üzerinden vekil sunucu olarak kullanmak için kullanılacaktır.",
156
155
  useCliCommand: "CLI Komutunu Kullan",
157
156
  close: "Kapat",
158
157
  requestVolume: "İstek Hacmi",
159
158
  filter: "Filtrele",
160
159
  all: "Tümü",
161
- none: "Hiçbiri",
162
160
  noDataTracked: "Henüz veri izlenmedi",
163
161
  selectFamilies: "Görüntülenecek aileleri seçin",
164
162
  selectModels: "Görüntülenecek modelleri seçin",
165
163
  noLogsMatch: "Filtreyle eşleşen günlük yok",
166
- connecting: "BAĞLANILIYOR",
164
+ connecting: "Bağlanılıyor",
167
165
  main: "Ana",
168
166
  system: "Sistem",
169
167
  refreshData: "Verileri Yenile",
@@ -172,7 +170,7 @@ window.translations.tr = {
172
170
  grepLogs: "günlükleri ara...",
173
171
  noMatchingModels: "Eşleşen model yok",
174
172
  typeToSearch: "Aramak veya seçmek için yazın...",
175
- or: "VEYA",
173
+ or: "veya",
176
174
  refreshingAccount: "{email} yenileniyor...",
177
175
  refreshedAccount: "{email} yenilendi",
178
176
  refreshFailed: "Yenileme başarısız",
@@ -199,8 +197,8 @@ window.translations.tr = {
199
197
  claudeEmpty: "Claude Boş",
200
198
  geminiActive: "Gemini Aktif",
201
199
  geminiEmpty: "Gemini Boş",
202
- synced: "EŞİTLENDİ",
203
- syncing: "EŞİTLENİYOR...",
200
+ synced: "Eşitlendi",
201
+ syncing: "Eşitleniyor...",
204
202
  // Time range labels
205
203
  last1Hour: "Son 1S",
206
204
  last6Hours: "Son 6S",
@@ -216,7 +214,7 @@ window.translations.tr = {
216
214
  production: "Üretim",
217
215
  configSaved: "Yapılandırma Kaydedildi",
218
216
  enterPassword: "Web UI Parolasını Girin:",
219
- ready: "HAZIR",
217
+ ready: "Hazır",
220
218
  depleted: "Tükendi",
221
219
  timeH: "S",
222
220
  timeM: "D",
@@ -225,19 +223,19 @@ window.translations.tr = {
225
223
  familyOther: "Diğer",
226
224
  enabledStatus: "etkin",
227
225
  disabledStatus: "devre dışı",
228
- logLevelInfo: "BİLGİ",
229
- logLevelSuccess: "BAŞARILI",
230
- logLevelWarn: "UYARI",
231
- logLevelError: "HATA",
226
+ logLevelInfo: "Bilgi",
227
+ logLevelSuccess: "Başarılı",
228
+ logLevelWarn: "Uyarı",
229
+ logLevelError: "Hata",
232
230
  totalColon: "Toplam:",
233
231
  todayColon: "Bugün:",
234
232
  hour1Colon: "1S:",
235
233
  frequentModels: "Sık Kullanılan",
236
234
  smartTitle: "En çok kullanılan 5 modeli otomatik seç (24s)",
237
235
  activeCount: "{count} Aktif",
238
- allCaps: "TÜMÜ",
239
- claudeCaps: "CLAUDE",
240
- geminiCaps: "GEMINI",
236
+ allCaps: "Tümü",
237
+ claudeCaps: "Claude",
238
+ geminiCaps: "Gemini",
241
239
  modelMapping: "Eşleştirme (Hedef Model ID)",
242
240
  systemInfo: "Sistem Bilgisi",
243
241
  refresh: "Yenile",
@@ -88,7 +88,6 @@ window.translations.zh = {
88
88
  toggleVisibility: "切换可见性",
89
89
  noModels: "未检测到模型",
90
90
  modelMappingHint: "服务端模型路由功能。Claude Code 用户请使用 'Claude CLI' 标签页以便捷配置。",
91
- modelMapping: "映射 (目标模型 ID)",
92
91
  // Settings - Claude
93
92
  proxyConnection: "代理连接",
94
93
  modelSelection: "模型选择",
@@ -179,7 +178,6 @@ window.translations.zh = {
179
178
  requestVolume: "请求量",
180
179
  filter: "筛选",
181
180
  all: "全选",
182
- none: "清空",
183
181
  noDataTracked: "暂无追踪数据",
184
182
  selectFamilies: "选择要显示的系列",
185
183
  selectModels: "选择要显示的模型",
@@ -21,7 +21,6 @@ window.ErrorHandler.safeAsync = async function(fn, errorMessage = null, options
21
21
  try {
22
22
  return await fn();
23
23
  } catch (error) {
24
- // Log error for debugging
25
24
  console.error(`[ErrorHandler] ${defaultErrorMessage}:`, error);
26
25
 
27
26
  // Show toast notification
@@ -86,7 +85,6 @@ window.ErrorHandler.withLoading = async function(asyncFn, context, loadingKey =
86
85
  context[loadingKey] = true;
87
86
 
88
87
  try {
89
- // Execute the async function with error handling
90
88
  const result = await window.ErrorHandler.safeAsync(asyncFn, options.errorMessage, options);
91
89
  return result;
92
90
  } finally {
@@ -28,7 +28,7 @@
28
28
  // Check localStorage
29
29
  try {
30
30
  return localStorage.getItem('ag_debug') === 'true';
31
- } catch (e) {
31
+ } catch {
32
32
  return false;
33
33
  }
34
34
  }
@@ -53,7 +53,7 @@
53
53
  debugEnabled = true;
54
54
  console.info('[UILogger] Debug mode enabled. Refresh page to see all logs.');
55
55
  } catch (e) {
56
- console.warn('[UILogger] Could not save debug preference');
56
+ console.warn('[UILogger] Could not save debug preference', e);
57
57
  }
58
58
  },
59
59
 
@@ -66,7 +66,7 @@
66
66
  debugEnabled = false;
67
67
  console.info('[UILogger] Debug mode disabled.');
68
68
  } catch (e) {
69
- // Ignore
69
+ console.warn('[UILogger] Could not clear debug preference', e);
70
70
  }
71
71
  },
72
72
 
@@ -103,6 +103,7 @@
103
103
  */
104
104
  log(...args) {
105
105
  if (debugEnabled) {
106
+ // aislop-ignore-next-line console-leftover -- UILogger's own output sink
106
107
  console.log(...args);
107
108
  }
108
109
  },
@@ -1,17 +1,13 @@
1
1
  <div x-data="accountManager" class="view-container">
2
2
  <!-- Compact Header -->
3
- <div class="flex items-center justify-between gap-4 mb-6">
4
- <!-- Title with inline subtitle -->
5
- <div class="flex flex-wrap items-center gap-4">
6
- <h1 class="text-2xl font-bold text-white tracking-tight" x-text="$store.global.t('accountManagement')">
3
+ <div class="flex items-end justify-between gap-4">
4
+ <div class="flex flex-col gap-1">
5
+ <h1 class="font-display text-[1.5rem] leading-tight font-bold text-white tracking-[-0.01em]" x-text="$store.global.t('accountManagement')">
7
6
  Account Management
8
7
  </h1>
9
- <div class="flex items-center h-6 px-3 rounded-full bg-space-800/80 border border-space-border/50 shadow-sm backdrop-blur-sm">
10
- <span class="text-[10px] font-mono text-gray-400 uppercase tracking-wider"
11
- x-text="$store.global.t('manageTokens')">
12
- Manage Google Account tokens and authorization states
13
- </span>
14
- </div>
8
+ <p class="text-sm text-gray-500" x-text="$store.global.t('manageTokens')">
9
+ Manage Google Account tokens and authorization states
10
+ </p>
15
11
  </div>
16
12
 
17
13
  <!-- Action Buttons -->
@@ -68,7 +64,7 @@
68
64
  :class="$store.data.accounts.length >= $store.data.maxAccounts ? 'text-yellow-400' : 'text-gray-400'"
69
65
  x-text="$store.data.accounts.length + '/' + $store.data.maxAccounts"></span>
70
66
  </div>
71
- <button class="btn bg-neon-purple hover:bg-purple-600 border-none text-white btn-xs gap-2 shadow-lg shadow-neon-purple/20 h-8"
67
+ <button class="btn bg-neon-purple hover:bg-[#7fdbe4] border-none text-space-950 btn-xs gap-2 h-8"
72
68
  :class="{ 'opacity-50 cursor-not-allowed': $store.data.accounts.length >= $store.data.maxAccounts }"
73
69
  :disabled="$store.data.accounts.length >= $store.data.maxAccounts"
74
70
  @click="$store.data.accounts.length < $store.data.maxAccounts && document.getElementById('add_account_modal').showModal()">
@@ -85,13 +81,13 @@
85
81
  <table class="w-full">
86
82
  <thead x-show="$store.data.accounts.length > 0">
87
83
  <tr class="bg-space-900/50 border-b border-space-border/50">
88
- <th class="pl-6 py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-16" x-text="$store.global.t('enabled')">Enabled</th>
89
- <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider flex-1 min-w-[200px]" x-text="$store.global.t('accountEmail')">Account (Email)</th>
90
- <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-20" x-text="$store.global.t('source')">Source</th>
91
- <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-16" x-text="$store.global.t('tier')">Tier</th>
92
- <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-32" x-text="$store.global.t('quota')">Quota</th>
93
- <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-24" x-text="$store.global.t('health')">Health</th>
94
- <th class="py-3 pr-6 text-right text-[10px] font-bold text-gray-500 uppercase tracking-wider w-32" x-text="$store.global.t('operations')">Operations</th>
84
+ <th class="pl-6 py-3 text-left text-[11px] font-medium text-gray-500 w-16" x-text="$store.global.t('enabled')">Enabled</th>
85
+ <th class="py-3 text-left text-[11px] font-medium text-gray-500 flex-1 min-w-[200px]" x-text="$store.global.t('accountEmail')">Account (Email)</th>
86
+ <th class="py-3 text-left text-[11px] font-medium text-gray-500 w-20" x-text="$store.global.t('source')">Source</th>
87
+ <th class="py-3 text-left text-[11px] font-medium text-gray-500 w-16" x-text="$store.global.t('tier')">Tier</th>
88
+ <th class="py-3 text-left text-[11px] font-medium text-gray-500 w-32" x-text="$store.global.t('quota')">Quota</th>
89
+ <th class="py-3 text-left text-[11px] font-medium text-gray-500 w-24" x-text="$store.global.t('health')">Health</th>
90
+ <th class="py-3 pr-6 text-right text-[11px] font-medium text-gray-500 w-32" x-text="$store.global.t('operations')">Operations</th>
95
91
  </tr>
96
92
  </thead>
97
93
  <tbody>
@@ -111,7 +107,7 @@
111
107
  Get started by adding a Google account via OAuth, or use the CLI command to import credentials.
112
108
  </p>
113
109
  <div class="flex items-center gap-4 mt-2">
114
- <button class="btn bg-neon-purple hover:bg-purple-600 border-none text-white btn-sm gap-2 shadow-lg shadow-neon-purple/20"
110
+ <button class="btn bg-neon-purple hover:bg-[#7fdbe4] border-none text-space-950 btn-sm gap-2"
115
111
  onclick="document.getElementById('add_account_modal').showModal()">
116
112
  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
117
113
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
@@ -181,7 +177,7 @@
181
177
  <span class="text-xs text-gray-600">-</span>
182
178
  </template>
183
179
  <div x-show="acc.quotaThreshold !== undefined"
184
- class="text-[10px] font-mono text-neon-yellow/60 mt-0.5"
180
+ class="text-[11px] font-mono text-neon-yellow/60 mt-0.5"
185
181
  x-text="'min: ' + getEffectiveThreshold(acc)"></div>
186
182
  </div>
187
183
  </td>
@@ -199,7 +195,7 @@
199
195
  x-text="acc.status.toUpperCase()">
200
196
  </span>
201
197
  <p x-show="acc.status === 'banned'"
202
- class="text-[9px] text-red-600/70 mt-0.5 max-w-[200px] leading-tight"
198
+ class="text-[10px] text-red-600/70 mt-0.5 max-w-[200px] leading-tight"
203
199
  x-text="acc.error || 'Gemini disabled for ToS violation'">
204
200
  </p>
205
201
  </div>
@@ -208,7 +204,7 @@
208
204
  <div class="flex justify-end gap-2">
209
205
  <!-- Fix Button -->
210
206
  <button x-show="acc.status === 'invalid'"
211
- class="px-3 py-1 text-[10px] font-bold font-mono uppercase tracking-wider rounded bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20 border border-yellow-500/30 hover:border-yellow-500/50 transition-all"
207
+ class="px-3 py-1 text-[11px] font-medium rounded bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20 border border-yellow-500/30 hover:border-yellow-500/50 transition-all"
212
208
  @click="fixAccount(acc.email)"
213
209
  x-text="$store.global.t('fix')">
214
210
  FIX
@@ -216,7 +212,7 @@
216
212
  <!-- Appeal Button (banned accounts only) -->
217
213
  <a x-show="acc.status === 'banned'"
218
214
  href="mailto:gemini-code-assist-user-feedback@google.com"
219
- class="px-3 py-1 text-[10px] font-bold font-mono uppercase tracking-wider rounded bg-red-900/20 text-red-400 hover:bg-red-900/30 border border-red-800/30 hover:border-red-800/50 transition-all"
215
+ class="px-3 py-1 text-[11px] font-medium rounded bg-red-900/20 text-red-400 hover:bg-red-900/30 border border-red-800/30 hover:border-red-800/50 transition-all"
220
216
  title="Email Google to appeal this ban">
221
217
  APPEAL
222
218
  </a>
@@ -293,7 +289,7 @@
293
289
  <button class="w-full flex items-center justify-between px-6 py-3 bg-space-900/50 border-b border-space-border/50 hover:bg-space-900/70 transition-colors"
294
290
  @click="$store.settings.toggle('healthInspectorOpen'); if ($store.settings.healthInspectorOpen && !healthData.strategy) fetchHealthData()">
295
291
  <div class="flex items-center gap-3">
296
- <span class="text-[9px] font-bold uppercase tracking-wider px-1.5 py-0.5 rounded bg-neon-purple/20 text-neon-purple border border-neon-purple/30">DEV</span>
292
+ <span class="text-[10px] font-medium px-1.5 py-0.5 rounded bg-neon-purple/20 text-neon-purple border border-neon-purple/30">DEV</span>
297
293
  <span class="text-sm font-semibold text-gray-300" x-text="$store.global.t('strategyHealthInspector')">Strategy Health Inspector</span>
298
294
  </div>
299
295
  <svg class="w-4 h-4 text-gray-500 transition-transform" :class="{ 'rotate-180': $store.settings.healthInspectorOpen }"
@@ -331,14 +327,14 @@
331
327
  <table class="w-full">
332
328
  <thead>
333
329
  <tr class="border-b border-space-border/50">
334
- <th class="py-2 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider">Email</th>
335
- <th class="py-2 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-40"
330
+ <th class="py-2 text-left text-[11px] font-medium text-gray-500">Email</th>
331
+ <th class="py-2 text-left text-[11px] font-medium text-gray-500 w-40"
336
332
  x-text="$store.global.t('healthScore')">Health Score</th>
337
- <th class="py-2 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-28"
333
+ <th class="py-2 text-left text-[11px] font-medium text-gray-500 w-28"
338
334
  x-text="$store.global.t('tokenBucket')">Tokens</th>
339
- <th class="py-2 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-20"
335
+ <th class="py-2 text-left text-[11px] font-medium text-gray-500 w-20"
340
336
  x-text="$store.global.t('consecutiveFailures')">Failures</th>
341
- <th class="py-2 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-20">Status</th>
337
+ <th class="py-2 text-left text-[11px] font-medium text-gray-500 w-20">Status</th>
342
338
  </tr>
343
339
  </thead>
344
340
  <tbody>
@@ -375,7 +371,7 @@
375
371
  x-text="acc.consecutiveFailures"></span>
376
372
  </td>
377
373
  <td class="py-2">
378
- <span class="text-[10px] font-bold uppercase px-1.5 py-0.5 rounded"
374
+ <span class="text-[11px] font-medium capitalize px-1.5 py-0.5 rounded"
379
375
  :class="acc.isUsable ? 'bg-neon-green/10 text-neon-green border border-neon-green/20' : 'bg-red-500/10 text-red-400 border border-red-500/20'"
380
376
  x-text="acc.isUsable ? 'OK' : 'DEGRADED'"></span>
381
377
  </td>
@@ -387,7 +383,7 @@
387
383
 
388
384
  <!-- Scoring reference -->
389
385
  <div x-show="healthData.trackers !== null && healthData.trackers?.accounts?.length > 0" class="mt-3 px-3 py-2 rounded bg-space-900/40 border border-space-border/30">
390
- <p class="text-[10px] text-gray-500 font-mono leading-relaxed">
386
+ <p class="text-[11px] text-gray-500 font-mono leading-relaxed">
391
387
  Score is adjusted for successes, rate limits, and failures with passive recovery.
392
388
  <br>
393
389
  Selection uses weighted health, token usage, quota, and recency (LRU).
@@ -444,7 +440,7 @@
444
440
  </dialog>
445
441
 
446
442
  <!-- Quota Distribution Modal -->
447
- <dialog id="quota_modal" class="modal backdrop-blur-sm">
443
+ <dialog id="quota_modal" class="modal">
448
444
  <div class="modal-box max-w-2xl w-full bg-space-900 border border-space-border text-gray-300 shadow-2xl p-6">
449
445
  <h3 class="font-bold text-xl text-white mb-2 flex items-center gap-2">
450
446
  <svg class="w-6 h-6 text-neon-cyan" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -474,9 +470,9 @@
474
470
  </div>
475
471
 
476
472
  <div class="flex justify-between items-center">
477
- <span class="text-[10px] text-gray-500 uppercase font-bold" x-text="$store.data.getModelFamily(modelId)"></span>
473
+ <span class="text-[11px] text-gray-500 capitalize font-medium" x-text="$store.data.getModelFamily(modelId)"></span>
478
474
  <template x-if="limit.resetTime">
479
- <span class="text-[10px] text-yellow-500/80 font-mono italic"
475
+ <span class="text-[11px] text-yellow-500/80 font-mono italic"
480
476
  x-text="$store.global.t('resetsIn', { time: window.utils.formatTimeUntil(limit.resetTime) })"></span>
481
477
  </template>
482
478
  </div>
@@ -502,7 +498,7 @@
502
498
  </dialog>
503
499
 
504
500
  <!-- Threshold Settings Modal -->
505
- <dialog id="threshold_modal" class="modal backdrop-blur-sm">
501
+ <dialog id="threshold_modal" class="modal">
506
502
  <div class="modal-box max-w-md w-full bg-space-900 border border-space-border text-gray-300 shadow-2xl p-6">
507
503
  <h3 class="font-bold text-xl text-white mb-2 flex items-center gap-2">
508
504
  <svg class="w-6 h-6 text-neon-yellow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -546,7 +542,7 @@
546
542
  <span class="text-gray-500 text-xs">%</span>
547
543
  </div>
548
544
  </div>
549
- <p class="text-[10px] text-gray-600 mt-1">
545
+ <p class="text-[11px] text-gray-600 mt-1">
550
546
  Leave empty to use the global threshold from Settings.
551
547
  </p>
552
548
  </div>
@@ -585,7 +581,7 @@
585
581
  :value="threshold"
586
582
  @input="updateModelThreshold(modelId, $event.target.value)"
587
583
  aria-label="Model threshold">
588
- <span class="text-gray-500 text-[10px]">%</span>
584
+ <span class="text-gray-500 text-[11px]">%</span>
589
585
  </div>
590
586
  <button class="btn btn-xs btn-ghost text-gray-500 hover:text-red-400 px-1"
591
587
  @click="removeModelThreshold(modelId)">
@@ -597,7 +593,7 @@
597
593
  </template>
598
594
 
599
595
  <template x-if="Object.keys(thresholdDialog.modelQuotaThresholds).length === 0">
600
- <p class="text-[10px] text-gray-600 text-center py-2">
596
+ <p class="text-[11px] text-gray-600 text-center py-2">
601
597
  No per-model overrides configured.
602
598
  </p>
603
599
  </template>