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
@@ -28,7 +28,7 @@ window.Components.logsViewer = () => ({
28
28
  try {
29
29
  const regex = new RegExp(query, 'i');
30
30
  matcher = (msg) => regex.test(msg);
31
- } catch (e) {
31
+ } catch {
32
32
  // Invalid regex, fallback to case-insensitive string search
33
33
  const lowerQuery = query.toLowerCase();
34
34
  matcher = (msg) => msg.toLowerCase().includes(lowerQuery);
@@ -6,16 +6,17 @@
6
6
  window.Components = window.Components || {};
7
7
 
8
8
  window.Components.models = () => ({
9
- // Color palette for per-account threshold markers
9
+ // Per-account threshold marker colours. They only tell accounts apart, so none of them
10
+ // reuses a status hue (green/amber/red); markers are flat ticks with no glow.
10
11
  thresholdColors: [
11
- { bg: '#eab308', shadow: 'rgba(234,179,8,0.5)' }, // yellow
12
- { bg: '#06b6d4', shadow: 'rgba(6,182,212,0.5)' }, // cyan
13
- { bg: '#a855f7', shadow: 'rgba(168,85,247,0.5)' }, // purple
14
- { bg: '#22c55e', shadow: 'rgba(34,197,94,0.5)' }, // green
15
- { bg: '#ef4444', shadow: 'rgba(239,68,68,0.5)' }, // red
16
- { bg: '#f97316', shadow: 'rgba(249,115,22,0.5)' }, // orange
17
- { bg: '#ec4899', shadow: 'rgba(236,72,153,0.5)' }, // pink
18
- { bg: '#8b5cf6', shadow: 'rgba(139,92,246,0.5)' }, // violet
12
+ { bg: '#eceae4', shadow: 'transparent' }, // lettering white
13
+ { bg: '#4cc9d6', shadow: 'transparent' }, // cyan
14
+ { bg: '#d9c39a', shadow: 'transparent' }, // sand
15
+ { bg: '#9aa7b0', shadow: 'transparent' }, // steel
16
+ { bg: '#7fdbe4', shadow: 'transparent' }, // pale cyan
17
+ { bg: '#bfa678', shadow: 'transparent' }, // khaki
18
+ { bg: '#c2a1bb', shadow: 'transparent' }, // dusty mauve
19
+ { bg: '#6f97a8', shadow: 'transparent' }, // slate blue
19
20
  ],
20
21
 
21
22
  getThresholdColor(index) {
@@ -32,7 +33,6 @@ window.Components.models = () => ({
32
33
  originalPct: 0
33
34
  },
34
35
 
35
- // Tracks which model rows have their per-account breakdown expanded beyond the cap
36
36
  expandedModels: new Set(),
37
37
 
38
38
  isExpanded(modelId) {
@@ -197,7 +197,7 @@ window.Components.models = () => ({
197
197
  const previousModelThresholds = account.modelQuotaThresholds ? { ...account.modelQuotaThresholds } : {};
198
198
 
199
199
  // Build full modelQuotaThresholds for API (full replacement, not merge)
200
- const existingModelThresholds = { ...(account.modelQuotaThresholds || {}) };
200
+ const existingModelThresholds = { ...account.modelQuotaThresholds };
201
201
 
202
202
  // Preserve the account-level quotaThreshold
203
203
  const quotaThreshold = account.quotaThreshold !== undefined ? account.quotaThreshold : null;
@@ -251,7 +251,7 @@ window.Components.models = () => ({
251
251
  * Markers within 2% of each other are considered overlapping.
252
252
  * Returns a CSS pixel offset string (e.g., '6px' or '-6px').
253
253
  */
254
- getMarkerOffset(q, row, qIdx) {
254
+ getMarkerOffset(q, row, _qIdx) {
255
255
  const pct = this.getMarkerPct(q, row);
256
256
  const visible = row.quotaInfo.filter(item => item.thresholdPct > 0 || this.isDragging(item, row));
257
257
  // Find all markers within 2% of this one
@@ -452,10 +452,6 @@ window.Components.serverConfig = () => ({
452
452
  return descriptions[strategy] || '';
453
453
  },
454
454
 
455
- // ==========================================
456
- // Server Configuration Presets
457
- // ==========================================
458
-
459
455
  async fetchServerPresets() {
460
456
  const password = Alpine.store('global').webuiPassword;
461
457
  try {
@@ -847,10 +843,6 @@ window.Components.serverConfig = () => ({
847
843
  };
848
844
  },
849
845
 
850
- // ==========================================
851
- // Inline Preset Config Editing
852
- // ==========================================
853
-
854
846
  /**
855
847
  * Flatten a nested config object into a flat draft for UI editing.
856
848
  * Converts fractions to percentages where needed.
@@ -1040,7 +1032,7 @@ window.Components.serverConfig = () => ({
1040
1032
  // Validate capacityBackoffTiersMs text
1041
1033
  this.validatePresetConfigField('capacityBackoffTiersMs', this.editingConfigDraft.capacityBackoffTiersMs);
1042
1034
  this.configEditMode = 'ui';
1043
- } catch (e) {
1035
+ } catch {
1044
1036
  this.jsonParseError = Alpine.store('global').t('invalidJson') || 'Invalid JSON';
1045
1037
  }
1046
1038
  }
@@ -51,7 +51,7 @@ document.addEventListener('alpine:init', () => {
51
51
  if (saved.placeholderMode) {
52
52
  this.setPlaceholderMode(true, saved.placeholderIncludeReal !== false);
53
53
  }
54
- } catch (e) { /* ignore parse errors */ }
54
+ } catch { /* ignore parse errors */ }
55
55
 
56
56
  // Watch filters to recompute
57
57
  // Alpine stores don't have $watch automatically unless inside a component?
@@ -187,7 +187,7 @@ document.addEventListener('alpine:init', () => {
187
187
  if (data.config) {
188
188
  this.devMode = !!data.config.devMode;
189
189
  }
190
- } catch (e) { /* ignore parse errors */ }
190
+ } catch { /* ignore parse errors */ }
191
191
  } else {
192
192
  this.connectionStatus = 'disconnected';
193
193
  }
@@ -68,7 +68,7 @@ document.addEventListener('alpine:init', () => {
68
68
  }
69
69
  }
70
70
  } catch (error) {
71
- console.debug('Could not fetch version:', error);
71
+ window.UILogger?.debug('Could not fetch version:', error);
72
72
  }
73
73
  },
74
74
 
@@ -8,23 +8,23 @@ window.translations.en = {
8
8
  accounts: "Accounts",
9
9
  logs: "Logs",
10
10
  settings: "Settings",
11
- online: "ONLINE",
12
- offline: "OFFLINE",
13
- totalAccounts: "TOTAL ACCOUNTS",
14
- active: "ACTIVE",
11
+ online: "Online",
12
+ offline: "Offline",
13
+ totalAccounts: "Total accounts",
14
+ active: "Active",
15
15
  operational: "Operational",
16
- rateLimited: "RATE LIMITED",
16
+ rateLimited: "Rate limited",
17
17
  quotasDepleted: "{count}/{total} Quotas Depleted",
18
- quotasDepletedTitle: "QUOTAS DEPLETED",
18
+ quotasDepletedTitle: "Quotas depleted",
19
19
  outOfTracked: "Out of {total} Tracked",
20
20
  cooldown: "Cooldown",
21
21
  searchPlaceholder: "Search models...",
22
22
  allAccounts: "All Accounts",
23
- stat: "STAT",
24
- modelIdentity: "MODEL IDENTITY",
25
- globalQuota: "GLOBAL QUOTA",
26
- nextReset: "NEXT RESET",
27
- distribution: "ACCOUNT DISTRIBUTION",
23
+ stat: "Stat",
24
+ modelIdentity: "Model identity",
25
+ globalQuota: "Global quota",
26
+ nextReset: "Next reset",
27
+ distribution: "Account distribution",
28
28
  systemConfig: "System Configuration",
29
29
  language: "Language",
30
30
  pollingInterval: "Polling Interval",
@@ -41,14 +41,14 @@ window.translations.en = {
41
41
  accountManagement: "Account Management",
42
42
  manageTokens: "Manage Google Account tokens and authorization states",
43
43
  addAccount: "Add Account",
44
- status: "STATUS",
45
- enabled: "ENABLED",
46
- health: "STATUS",
47
- accountEmail: "ACCOUNT (EMAIL)",
48
- source: "SOURCE",
49
- projectId: "PROJECT ID",
50
- sessionState: "SESSION STATE",
51
- operations: "OPERATIONS",
44
+ status: "Status",
45
+ enabled: "Enabled",
46
+ health: "Status",
47
+ accountEmail: "Account (email)",
48
+ source: "Source",
49
+ projectId: "Project ID",
50
+ sessionState: "Session state",
51
+ operations: "Operations",
52
52
  delete: "Delete",
53
53
  fix: "Fix",
54
54
  confirmDelete: "Are you sure you want to remove this account?",
@@ -72,8 +72,8 @@ window.translations.en = {
72
72
  tabServer: "Server Settings",
73
73
  // Dashboard
74
74
  linkedAccounts: "Linked Accounts",
75
- noSignal: "NO SIGNAL DETECTED",
76
- establishingUplink: "ESTABLISHING UPLINK...",
75
+ noSignal: "No signal detected",
76
+ establishingUplink: "Establishing uplink...",
77
77
  goToAccounts: "Go to Accounts",
78
78
  // Settings - Models
79
79
  modelsDesc: "Configure model visibility, pinning, and request routing.",
@@ -86,13 +86,12 @@ window.translations.en = {
86
86
  actions: "Actions",
87
87
  pinToTop: "Pin to top",
88
88
  toggleVisibility: "Toggle Visibility",
89
- noModels: "NO MODELS DETECTED",
89
+ noModels: "No models detected",
90
90
  modelMappingHint: "Server-side model routing. Claude Code users: see 'Claude CLI' tab for client-side setup.",
91
- modelMapping: "Mapping (Target Model ID)",
92
91
  // Settings - Claude
93
92
  proxyConnection: "Proxy Connection",
94
93
  modelSelection: "Model Selection",
95
- defaultModelAliases: "DEFAULT MODEL ALIASES",
94
+ defaultModelAliases: "Default model aliases",
96
95
  opusAlias: "Opus Alias",
97
96
  sonnetAlias: "Sonnet Alias",
98
97
  haikuAlias: "Haiku Alias",
@@ -171,20 +170,19 @@ window.translations.en = {
171
170
  saveConfig: "Save to Claude CLI settings",
172
171
  envVar: "Env",
173
172
  // New Keys
174
- systemName: "ANTIGRAVITY",
175
- systemDesc: "CLAUDE PROXY SYSTEM",
173
+ systemName: "Antigravity",
174
+ systemDesc: "Claude proxy",
176
175
  connectGoogleDesc: "Connect a Google Workspace account to increase your API quota limit. The account will be used to proxy Claude requests via Antigravity.",
177
176
  useCliCommand: "Use CLI Command",
178
177
  close: "Close",
179
178
  requestVolume: "Request Volume",
180
179
  filter: "Filter",
181
180
  all: "All",
182
- none: "None",
183
181
  noDataTracked: "No data tracked yet",
184
182
  selectFamilies: "Select families to display",
185
183
  selectModels: "Select models to display",
186
184
  noLogsMatch: "No logs match filter",
187
- connecting: "CONNECTING",
185
+ connecting: "Connecting",
188
186
  main: "Main",
189
187
  system: "System",
190
188
  refreshData: "Refresh Data",
@@ -193,7 +191,7 @@ window.translations.en = {
193
191
  grepLogs: "grep logs...",
194
192
  noMatchingModels: "No matching models",
195
193
  typeToSearch: "Type to search or select...",
196
- or: "OR",
194
+ or: "or",
197
195
  refreshingAccount: "Refreshing {email}...",
198
196
  refreshedAccount: "Refreshed {email}",
199
197
  refreshFailed: "Refresh failed",
@@ -217,8 +215,8 @@ window.translations.en = {
217
215
  claudeEmpty: "Claude Empty",
218
216
  geminiActive: "Gemini Active",
219
217
  geminiEmpty: "Gemini Empty",
220
- synced: "SYNCED",
221
- syncing: "SYNCING...",
218
+ synced: "Synced",
219
+ syncing: "Syncing...",
222
220
  // Time range labels
223
221
  last1Hour: "Last 1H",
224
222
  last6Hours: "Last 6H",
@@ -234,7 +232,7 @@ window.translations.en = {
234
232
  production: "Production",
235
233
  configSaved: "Configuration Saved",
236
234
  enterPassword: "Enter Web UI Password:",
237
- ready: "READY",
235
+ ready: "Ready",
238
236
  depleted: "Depleted",
239
237
  timeH: "H",
240
238
  timeM: "M",
@@ -243,19 +241,19 @@ window.translations.en = {
243
241
  familyOther: "Other",
244
242
  enabledStatus: "enabled",
245
243
  disabledStatus: "disabled",
246
- logLevelInfo: "INFO",
247
- logLevelSuccess: "SUCCESS",
248
- logLevelWarn: "WARN",
249
- logLevelError: "ERR",
244
+ logLevelInfo: "Info",
245
+ logLevelSuccess: "Success",
246
+ logLevelWarn: "Warn",
247
+ logLevelError: "Error",
250
248
  totalColon: "Total:",
251
249
  todayColon: "Today:",
252
250
  hour1Colon: "1H:",
253
251
  frequentModels: "Frequent",
254
252
  smartTitle: "Auto-select top 5 most used models (24h)",
255
253
  activeCount: "{count} Active",
256
- allCaps: "ALL",
257
- claudeCaps: "CLAUDE",
258
- geminiCaps: "GEMINI",
254
+ allCaps: "All",
255
+ claudeCaps: "Claude",
256
+ geminiCaps: "Gemini",
259
257
  modelMapping: "Mapping (Target Model ID)",
260
258
  systemInfo: "System Information",
261
259
  refresh: "Refresh",
@@ -16,25 +16,25 @@ window.translations.id = {
16
16
  settings: "Pengaturan",
17
17
 
18
18
  // Status
19
- online: "ONLINE",
20
- offline: "OFFLINE",
21
- totalAccounts: "TOTAL AKUN",
22
- active: "AKTIF",
19
+ online: "Online",
20
+ offline: "Offline",
21
+ totalAccounts: "Total akun",
22
+ active: "Aktif",
23
23
  operational: "Berjalan Normal",
24
- rateLimited: "DIBATASI",
24
+ rateLimited: "Dibatasi",
25
25
  quotasDepleted: "{count}/{total} Kuota Habis",
26
- quotasDepletedTitle: "KUOTA HABIS",
26
+ quotasDepletedTitle: "Kuota habis",
27
27
  outOfTracked: "Dari {total} Terpantau",
28
28
  cooldown: "Cooldown",
29
29
 
30
30
  // Search & Filters
31
31
  searchPlaceholder: "Cari model...",
32
32
  allAccounts: "Semua Akun",
33
- stat: "STATUS",
34
- modelIdentity: "IDENTITAS MODEL",
35
- globalQuota: "KUOTA GLOBAL",
36
- nextReset: "RESET BERIKUTNYA",
37
- distribution: "DISTRIBUSI AKUN",
33
+ stat: "Status",
34
+ modelIdentity: "Identitas model",
35
+ globalQuota: "Kuota global",
36
+ nextReset: "Reset berikutnya",
37
+ distribution: "Distribusi akun",
38
38
 
39
39
  // System Configuration
40
40
  systemConfig: "Konfigurasi Sistem",
@@ -57,14 +57,14 @@ window.translations.id = {
57
57
  accountManagement: "Kelola Akun",
58
58
  manageTokens: "Kelola token akun Google dan status otorisasi",
59
59
  addAccount: "Tambah Akun",
60
- status: "STATUS",
61
- enabled: "AKTIF",
62
- health: "STATUS",
63
- accountEmail: "AKUN (EMAIL)",
64
- source: "SUMBER",
65
- projectId: "PROJECT ID",
66
- sessionState: "STATUS SESI",
67
- operations: "AKSI",
60
+ status: "Status",
61
+ enabled: "Aktif",
62
+ health: "Status",
63
+ accountEmail: "Akun (email)",
64
+ source: "Sumber",
65
+ projectId: "Project ID",
66
+ sessionState: "Status sesi",
67
+ operations: "Aksi",
68
68
  delete: "Hapus",
69
69
  confirmDelete: "Yakin ingin menghapus akun ini?",
70
70
  cannotDeleteDatabase: "Tidak bisa dihapus: Akun ini dari database Antigravity (read-only)",
@@ -90,8 +90,8 @@ window.translations.id = {
90
90
 
91
91
  // Dashboard
92
92
  linkedAccounts: "Akun Terhubung",
93
- noSignal: "TIDAK ADA SINYAL",
94
- establishingUplink: "MENGHUBUNGKAN...",
93
+ noSignal: "Tidak ada sinyal",
94
+ establishingUplink: "Menghubungkan...",
95
95
  goToAccounts: "Lihat Akun",
96
96
 
97
97
  // Settings - Models
@@ -105,14 +105,14 @@ window.translations.id = {
105
105
  actions: "Aksi",
106
106
  pinToTop: "Pin ke atas",
107
107
  toggleVisibility: "Tampilkan/Sembunyikan",
108
- noModels: "MODEL TIDAK DITEMUKAN",
108
+ noModels: "Model tidak ditemukan",
109
109
  modelMappingHint: "Routing model di sisi server. Pengguna Claude Code: lihat tab 'Claude CLI' untuk pengaturan di sisi klien.",
110
110
  modelMapping: "Mapping (Target Model ID)",
111
111
 
112
112
  // Settings - Claude
113
113
  proxyConnection: "Koneksi Proxy",
114
114
  modelSelection: "Pilihan Model",
115
- defaultModelAliases: "ALIAS MODEL DEFAULT",
115
+ defaultModelAliases: "Alias model default",
116
116
  opusAlias: "Alias Opus",
117
117
  sonnetAlias: "Alias Sonnet",
118
118
  haikuAlias: "Alias Haiku",
@@ -195,8 +195,8 @@ window.translations.id = {
195
195
  envVar: "Env",
196
196
 
197
197
  // System
198
- systemName: "ANTIGRAVITY",
199
- systemDesc: "CLAUDE PROXY SYSTEM",
198
+ systemName: "Antigravity",
199
+ systemDesc: "Claude proxy system",
200
200
  connectGoogleDesc: "Hubungkan akun Google Workspace untuk meningkatkan kuota API. Akun akan digunakan untuk meneruskan request Claude via Antigravity.",
201
201
  useCliCommand: "Gunakan Perintah CLI",
202
202
  close: "Tutup",
@@ -208,7 +208,7 @@ window.translations.id = {
208
208
  selectFamilies: "Pilih jenis model untuk ditampilkan",
209
209
  selectModels: "Pilih model untuk ditampilkan",
210
210
  noLogsMatch: "Tidak ada log yang sesuai filter",
211
- connecting: "MENGHUBUNGKAN",
211
+ connecting: "Menghubungkan",
212
212
  main: "Utama",
213
213
  system: "Sistem",
214
214
  refreshData: "Refresh Data",
@@ -217,7 +217,7 @@ window.translations.id = {
217
217
  grepLogs: "cari log...",
218
218
  noMatchingModels: "Tidak ada model yang cocok",
219
219
  typeToSearch: "Ketik untuk mencari...",
220
- or: "ATAU",
220
+ or: "atau",
221
221
 
222
222
  // Account Operations
223
223
  refreshingAccount: "Memperbarui {email}...",
@@ -228,7 +228,6 @@ window.translations.id = {
228
228
  reauthenticating: "Autentikasi ulang {email}...",
229
229
  authUrlFailed: "Gagal mendapatkan URL autentikasi",
230
230
  deletedAccount: "{email} berhasil dihapus",
231
- deleteFailed: "Gagal menghapus",
232
231
  accountsReloaded: "Akun berhasil dimuat ulang",
233
232
  reloadFailed: "Gagal memuat ulang",
234
233
 
@@ -247,8 +246,8 @@ window.translations.id = {
247
246
  claudeEmpty: "Claude Kosong",
248
247
  geminiActive: "Gemini Aktif",
249
248
  geminiEmpty: "Gemini Kosong",
250
- synced: "SINKRON",
251
- syncing: "SINKRONISASI...",
249
+ synced: "Sinkron",
250
+ syncing: "Sinkronisasi...",
252
251
 
253
252
  // Time range labels
254
253
  last1Hour: "1 Jam Terakhir",
@@ -266,7 +265,7 @@ window.translations.id = {
266
265
  production: "Produksi",
267
266
  configSaved: "Konfigurasi Tersimpan",
268
267
  enterPassword: "Masukkan Password Web UI:",
269
- ready: "SIAP",
268
+ ready: "Siap",
270
269
  depleted: "Habis",
271
270
  timeH: "j",
272
271
  timeM: "m",
@@ -275,19 +274,19 @@ window.translations.id = {
275
274
  familyOther: "Lainnya",
276
275
  enabledStatus: "diaktifkan",
277
276
  disabledStatus: "dinonaktifkan",
278
- logLevelInfo: "INFO",
277
+ logLevelInfo: "Info",
279
278
  logLevelSuccess: "OK",
280
- logLevelWarn: "WARN",
281
- logLevelError: "ERROR",
279
+ logLevelWarn: "Warn",
280
+ logLevelError: "Error",
282
281
  totalColon: "Total:",
283
282
  todayColon: "Hari Ini:",
284
283
  hour1Colon: "1j:",
285
284
  frequentModels: "Sering Dipakai",
286
285
  smartTitle: "Otomatis pilih 5 model paling sering dipakai (24 jam)",
287
286
  activeCount: "{count} Aktif",
288
- allCaps: "SEMUA",
289
- claudeCaps: "CLAUDE",
290
- geminiCaps: "GEMINI",
287
+ allCaps: "Semua",
288
+ claudeCaps: "Claude",
289
+ geminiCaps: "Gemini",
291
290
 
292
291
  // System Info
293
292
  systemInfo: "Informasi Sistem",
@@ -9,23 +9,23 @@ window.translations.pt = {
9
9
  accounts: "Contas",
10
10
  logs: "Logs",
11
11
  settings: "Configurações",
12
- online: "ONLINE",
13
- offline: "OFFLINE",
14
- totalAccounts: "TOTAL DE CONTAS",
15
- active: "ATIVO",
12
+ online: "Online",
13
+ offline: "Offline",
14
+ totalAccounts: "Total de contas",
15
+ active: "Ativo",
16
16
  operational: "Operacional",
17
- rateLimited: "TAXA LIMITADA",
17
+ rateLimited: "Taxa limitada",
18
18
  quotasDepleted: "{count}/{total} Cotas Esgotadas",
19
- quotasDepletedTitle: "COTAS ESGOTADAS",
19
+ quotasDepletedTitle: "Cotas esgotadas",
20
20
  outOfTracked: "De {total} Rastreados",
21
21
  cooldown: "Resfriamento",
22
22
  searchPlaceholder: "Buscar modelos...",
23
23
  allAccounts: "Todas as Contas",
24
- stat: "ESTATÍSTICA",
25
- modelIdentity: "IDENTIDADE DO MODELO",
26
- globalQuota: "COTA GLOBAL",
27
- nextReset: "PRÓXIMO RESET",
28
- distribution: "DISTRIBUIÇÃO DE CONTAS",
24
+ stat: "Estatística",
25
+ modelIdentity: "Identidade do modelo",
26
+ globalQuota: "Cota global",
27
+ nextReset: "Próximo reset",
28
+ distribution: "Distribuição de contas",
29
29
  systemConfig: "Configuração do Sistema",
30
30
  language: "Idioma",
31
31
  pollingInterval: "Intervalo de Atualização",
@@ -42,14 +42,14 @@ window.translations.pt = {
42
42
  accountManagement: "Gerenciamento de Contas",
43
43
  manageTokens: "Gerenciar tokens e estados de autorização de Contas Google",
44
44
  addAccount: "Adicionar Conta",
45
- status: "STATUS",
46
- enabled: "HABILITADO",
47
- health: "SAÚDE",
48
- accountEmail: "CONTA (EMAIL)",
49
- source: "FONTE",
50
- projectId: "ID DO PROJETO",
51
- sessionState: "ESTADO DA SESSÃO",
52
- operations: "OPERAÇÕES",
45
+ status: "Status",
46
+ enabled: "Habilitado",
47
+ health: "Saúde",
48
+ accountEmail: "Conta (email)",
49
+ source: "Fonte",
50
+ projectId: "ID do projeto",
51
+ sessionState: "Estado da sessão",
52
+ operations: "Operações",
53
53
  delete: "Excluir",
54
54
  confirmDelete: "Tem certeza de que deseja remover esta conta?",
55
55
  cannotDeleteDatabase: "Não é possível excluir: Esta conta é do banco de dados Antigravity (somente leitura)",
@@ -72,8 +72,8 @@ window.translations.pt = {
72
72
  tabServer: "Configurações do Servidor",
73
73
  // Dashboard
74
74
  linkedAccounts: "Contas Vinculadas",
75
- noSignal: "SEM SINAL DETECTADO",
76
- establishingUplink: "ESTABELECENDO LINK...",
75
+ noSignal: "Sem sinal detectado",
76
+ establishingUplink: "Estabelecendo link...",
77
77
  goToAccounts: "Ir para Contas",
78
78
  // Settings - Models
79
79
  modelsDesc: "Configurar visibilidade, fixação e roteamento de requisições de modelos.",
@@ -83,13 +83,13 @@ window.translations.pt = {
83
83
  actions: "Ações",
84
84
  pinToTop: "Fixar no topo",
85
85
  toggleVisibility: "Alternar Visibilidade",
86
- noModels: "NENHUM MODELO DETECTADO",
86
+ noModels: "Nenhum modelo detectado",
87
87
  modelMappingHint: "Roteamento de modelo no servidor. Usuários do Claude Code: veja a aba 'Claude CLI' para configuração no cliente.",
88
88
  modelMapping: "Mapeamento (ID do Modelo Alvo)",
89
89
  // Settings - Claude
90
90
  proxyConnection: "Conexão Proxy",
91
91
  modelSelection: "Seleção de Modelo",
92
- defaultModelAliases: "ALIASES DE MODELO PADRÃO",
92
+ defaultModelAliases: "Aliases de modelo padrão",
93
93
  opusAlias: "Alias Opus",
94
94
  sonnetAlias: "Alias Sonnet",
95
95
  haikuAlias: "Alias Haiku",
@@ -147,20 +147,19 @@ window.translations.pt = {
147
147
  saveConfig: "Salvar nas configurações do Claude CLI",
148
148
  envVar: "Env",
149
149
  // New Keys
150
- systemName: "ANTIGRAVITY",
151
- systemDesc: "SISTEMA DE PROXY CLAUDE",
150
+ systemName: "Antigravity",
151
+ systemDesc: "Sistema de proxy Claude",
152
152
  connectGoogleDesc: "Conecte uma conta Google Workspace para aumentar seu limite de cota da API. A conta será usada para fazer proxy das requisições Claude via Antigravity.",
153
153
  useCliCommand: "Usar Comando CLI",
154
154
  close: "Fechar",
155
155
  requestVolume: "Volume de Requisições",
156
156
  filter: "Filtrar",
157
157
  all: "Todos",
158
- none: "Nenhum",
159
158
  noDataTracked: "Nenhum dado rastreado ainda",
160
159
  selectFamilies: "Selecione famílias para exibir",
161
160
  selectModels: "Selecione modelos para exibir",
162
161
  noLogsMatch: "Nenhum log corresponde ao filtro",
163
- connecting: "CONECTANDO",
162
+ connecting: "Conectando",
164
163
  main: "Principal",
165
164
  system: "Sistema",
166
165
  refreshData: "Atualizar Dados",
@@ -169,7 +168,7 @@ window.translations.pt = {
169
168
  grepLogs: "grep logs...",
170
169
  noMatchingModels: "Nenhum modelo correspondente",
171
170
  typeToSearch: "Digite para buscar ou selecione...",
172
- or: "OU",
171
+ or: "ou",
173
172
  refreshingAccount: "Atualizando {email}...",
174
173
  refreshedAccount: "Atualizado {email}",
175
174
  refreshFailed: "Falha na atualização",
@@ -196,8 +195,8 @@ window.translations.pt = {
196
195
  claudeEmpty: "Claude Vazio",
197
196
  geminiActive: "Gemini Ativo",
198
197
  geminiEmpty: "Gemini Vazio",
199
- synced: "SINCRONIZADO",
200
- syncing: "SINCRONIZANDO...",
198
+ synced: "Sincronizado",
199
+ syncing: "Sincronizando...",
201
200
  // Time range labels
202
201
  last1Hour: "Última 1H",
203
202
  last6Hours: "Últimas 6H",
@@ -213,7 +212,7 @@ window.translations.pt = {
213
212
  production: "Produção",
214
213
  configSaved: "Configuração Salva",
215
214
  enterPassword: "Digite a Senha da Web UI:",
216
- ready: "PRONTO",
215
+ ready: "Pronto",
217
216
  depleted: "Esgotado",
218
217
  timeH: "H",
219
218
  timeM: "M",
@@ -222,19 +221,19 @@ window.translations.pt = {
222
221
  familyOther: "Outro",
223
222
  enabledStatus: "habilitado",
224
223
  disabledStatus: "desabilitado",
225
- logLevelInfo: "INFO",
226
- logLevelSuccess: "SUCESSO",
227
- logLevelWarn: "AVISO",
228
- logLevelError: "ERRO",
224
+ logLevelInfo: "Info",
225
+ logLevelSuccess: "Sucesso",
226
+ logLevelWarn: "Aviso",
227
+ logLevelError: "Erro",
229
228
  totalColon: "Total:",
230
229
  todayColon: "Hoje:",
231
230
  hour1Colon: "1H:",
232
231
  frequentModels: "Frequentes",
233
232
  smartTitle: "Auto-selecionar os 5 modelos mais usados (24h)",
234
233
  activeCount: "{count} Ativos",
235
- allCaps: "TODOS",
236
- claudeCaps: "CLAUDE",
237
- geminiCaps: "GEMINI",
234
+ allCaps: "Todos",
235
+ claudeCaps: "Claude",
236
+ geminiCaps: "Gemini",
238
237
  systemInfo: "Informações do Sistema",
239
238
  refresh: "Atualizar",
240
239
  runtimeConfig: "Configuração em Tempo de Execução",