/** * Global Store for Antigravity Console * Handles Translations, Toasts, and Shared Config */ document.addEventListener('alpine:init', () => { Alpine.store('global', { // App State version: '1.0.0', activeTab: 'dashboard', webuiPassword: localStorage.getItem('antigravity_webui_password') || '', // i18n lang: localStorage.getItem('app_lang') || 'en', translations: { en: { dashboard: "Dashboard", models: "Models", accounts: "Accounts", logs: "Logs", settings: "Settings", online: "ONLINE", offline: "OFFLINE", totalAccounts: "TOTAL ACCOUNTS", active: "ACTIVE", operational: "Operational", rateLimited: "RATE LIMITED", cooldown: "Cooldown", searchPlaceholder: "Search models...", allAccounts: "All Accounts", stat: "STAT", modelIdentity: "MODEL IDENTITY", globalQuota: "GLOBAL QUOTA", nextReset: "NEXT RESET", distribution: "ACCOUNT DISTRIBUTION", systemConfig: "System Configuration", language: "Language", pollingInterval: "Polling Interval", logBufferSize: "Log Buffer Size", showExhausted: "Show Exhausted Models", showExhaustedDesc: "Display models even if they have 0% remaining quota.", compactMode: "Compact Mode", compactModeDesc: "Reduce padding in tables for higher information density.", saveChanges: "Save Changes", autoScroll: "Auto-scroll", clearLogs: "Clear Logs", accessCredentials: "Access Credentials", manageTokens: "Manage OAuth tokens and session states", addNode: "Add Node", status: "STATUS", enabled: "ENABLED", health: "HEALTH", identity: "IDENTITY (EMAIL)", source: "SOURCE", projectId: "PROJECT ID", sessionState: "SESSION STATE", operations: "OPERATIONS", delete: "Delete", confirmDelete: "Are you sure you want to remove this account?", cannotDeleteDatabase: "Cannot delete: This account is from Antigravity database (read-only)", connectGoogle: "Connect Google Account", reauthenticated: "re-authenticated", added: "added", successfully: "successfully", failedToGetAuthUrl: "Failed to get auth URL", failedToStartOAuth: "Failed to start OAuth flow", oauthInProgress: "OAuth in progress. Please complete authentication in the popup window...", family: "Family", model: "Model", activeSuffix: "Active", // Tabs tabInterface: "Interface", tabClaude: "Claude CLI", tabModels: "Models", tabServer: "Server Info", // Dashboard registeredNodes: "Registered Nodes", noSignal: "NO SIGNAL DETECTED", establishingUplink: "ESTABLISHING UPLINK...", // Settings - Models modelsDesc: "Configure model visibility, pinning, and request redirection.", modelsPageDesc: "Real-time quota and status for all available models.", showHidden: "Show Hidden Models", modelId: "Model ID", actions: "Actions", pinToTop: "Pin to top", toggleVisibility: "Toggle Visibility", noModels: "NO MODELS DETECTED", modelMappingHint: "Server-side model redirection. Claude Code users: see 'Claude CLI' tab for easier setup.", modelMapping: "Mapping (Target Model)", // Settings - Claude proxyConnection: "Proxy Connection", modelSelection: "Model Selection", aliasOverrides: "ALIAS OVERRIDES", opusAlias: "Opus Alias", sonnetAlias: "Sonnet Alias", haikuAlias: "Haiku Alias", claudeSettingsAlert: "Settings below directly modify ~/.claude/settings.json. Restart Claude CLI to apply.", writeToConfig: "Write to Config", // Settings - Server port: "Port", uiVersion: "UI Version", debugMode: "Debug Mode", environment: "Environment", serverReadOnly: "Server settings are read-only. Modify config.json or .env and restart the server to change.", dangerZone: "Danger Zone / Advanced", reloadConfigTitle: "Reload Account Config", reloadConfigDesc: "Force reload accounts.json from disk", reload: "Reload", // Config Specific primaryModel: "Primary Model", subAgentModel: "Sub-agent Model", advancedOverrides: "Default Model Overrides", opusModel: "Opus Model", sonnetModel: "Sonnet Model", haikuModel: "Haiku Model", authToken: "Auth Token", saveConfig: "Save to ~/.claude/settings.json", envVar: "Env", // New Keys systemName: "ANTIGRAVITY", systemDesc: "CLAUDE PROXY SYSTEM", connectGoogleDesc: "Connect a Google Workspace account to increase your API quota limit. The account will be used to proxy Claude requests via Antigravity.", useCliCommand: "Use CLI Command", close: "Close", requestVolume: "Request Volume", filter: "Filter", all: "All", none: "None", noDataTracked: "No data tracked yet", selectFamilies: "Select families to display", selectModels: "Select models to display", noLogsMatch: "No logs match filter", connecting: "CONNECTING", main: "Main", system: "System", refreshData: "Refresh Data", connectionLost: "Connection Lost", lastUpdated: "Last Updated", grepLogs: "grep logs...", noMatchingModels: "No matching models", typeToSearch: "Type to search or select...", or: "OR", refreshingAccount: "Refreshing {email}...", refreshedAccount: "Refreshed {email}", refreshFailed: "Refresh failed", accountToggled: "Account {email} {status}", toggleFailed: "Toggle failed", reauthenticating: "Re-authenticating {email}...", authUrlFailed: "Failed to get auth URL", deletedAccount: "Deleted {email}", deleteFailed: "Delete failed", accountsReloaded: "Accounts reloaded", reloadFailed: "Reload failed", claudeConfigSaved: "Claude configuration saved", saveConfigFailed: "Failed to save configuration", claudeActive: "Claude Active", claudeEmpty: "Claude Empty", geminiActive: "Gemini Active", geminiEmpty: "Gemini Empty", fix: "FIX", synced: "SYNCED", syncing: "SYNCING...", // Additional reloading: "Reloading...", reloaded: "Reloaded", lines: "lines", enabledSeeLogs: "Enabled (See Logs)", production: "Production", configSaved: "Configuration Saved", enterPassword: "Enter Web UI Password:", ready: "READY", depleted: "Depleted", timeH: "H", timeM: "M", familyClaude: "Claude", familyGemini: "Gemini", familyOther: "Other", enabledStatus: "enabled", disabledStatus: "disabled", logLevelInfo: "INFO", logLevelSuccess: "SUCCESS", logLevelWarn: "WARN", logLevelError: "ERR", totalColon: "Total:", todayColon: "Today:", hour1Colon: "1H:", smart: "Smart", smartTitle: "Select Top 5 most used models (24h)", activeCount: "{count} Active", allCaps: "ALL", claudeCaps: "CLAUDE", geminiCaps: "GEMINI", modelMapping: "Mapping (Target Model ID)", systemInfo: "System Information", refresh: "Refresh", runtimeConfig: "Runtime Configuration", debugDesc: "Enable detailed logging (See Logs tab)", networkRetry: "Network Retry Settings", maxRetries: "Max Retries", retryBaseDelay: "Retry Base Delay (ms)", retryMaxDelay: "Retry Max Delay (ms)", persistTokenCache: "Persist Token Cache", persistTokenDesc: "Save OAuth tokens to disk for faster restarts", rateLimiting: "Account Rate Limiting & Timeouts", defaultCooldown: "Default Cooldown Time", maxWaitThreshold: "Max Wait Threshold (Sticky)", maxWaitDesc: "Maximum time to wait for a sticky account to reset before failing or switching.", saveConfigServer: "Save Configuration", serverRestartAlert: "Some changes may require server restart. Config is saved to {path}", changePassword: "Change WebUI Password", changePasswordDesc: "Update the password for accessing this dashboard", currentPassword: "Current Password", newPassword: "New Password", confirmNewPassword: "Confirm New Password", passwordEmptyDesc: "Leave empty if no password set", passwordLengthDesc: "At least 6 characters", passwordConfirmDesc: "Re-enter new password", cancel: "Cancel", passwordsNotMatch: "Passwords do not match", passwordTooShort: "Password must be at least 6 characters", }, zh: { dashboard: "仪表盘", models: "模型列表", accounts: "账号管理", logs: "运行日志", settings: "系统设置", online: "在线", offline: "离线", totalAccounts: "账号总数", active: "活跃状态", operational: "运行中", rateLimited: "受限状态", cooldown: "冷却中", searchPlaceholder: "搜索模型...", allAccounts: "所有账号", stat: "状态", modelIdentity: "模型标识", globalQuota: "全局配额", nextReset: "重置时间", distribution: "账号分布", systemConfig: "系统配置", language: "语言设置", pollingInterval: "数据轮询间隔", logBufferSize: "日志缓冲大小", showExhausted: "显示耗尽模型", showExhaustedDesc: "即使配额为 0% 也显示模型。", compactMode: "紧凑模式", compactModeDesc: "减少表格间距以显示更多信息。", saveChanges: "保存更改", autoScroll: "自动滚动", clearLogs: "清除日志", accessCredentials: "访问凭证", manageTokens: "管理 OAuth 令牌和会话状态", addNode: "添加节点", status: "状态", enabled: "启用", health: "健康度", identity: "身份 (邮箱)", source: "来源", projectId: "项目 ID", sessionState: "会话状态", operations: "操作", delete: "删除", confirmDelete: "确定要移除此账号吗?", cannotDeleteDatabase: "无法删除:此账号来自 Antigravity 数据库(只读)", connectGoogle: "连接 Google 账号", reauthenticated: "已重新认证", added: "已添加", successfully: "成功", failedToGetAuthUrl: "获取认证链接失败", failedToStartOAuth: "启动 OAuth 流程失败", oauthInProgress: "OAuth 授权进行中,请在弹出窗口中完成认证...", family: "系列", model: "模型", activeSuffix: "活跃", manualReload: "重新加载配置", // Tabs tabInterface: "界面设置", tabClaude: "Claude CLI", tabModels: "模型管理", tabServer: "服务器信息", // Dashboard registeredNodes: "已注册节点", noSignal: "无信号连接", establishingUplink: "正在建立上行链路...", // Settings - Models modelsDesc: "配置模型的可见性、置顶和请求重定向。", modelsPageDesc: "所有可用模型的实时配额和状态。", showHidden: "显示隐藏模型", modelId: "模型 ID", actions: "操作", pinToTop: "置顶", toggleVisibility: "切换可见性", noModels: "未检测到模型", modelMappingHint: "服务端模型重定向功能。Claude Code 用户请使用 'Claude CLI' 标签页以便捷配置。", modelMapping: "映射 (目标模型)", // Settings - Claude proxyConnection: "代理连接", modelSelection: "模型选择", aliasOverrides: "别名覆盖", opusAlias: "Opus 别名", sonnetAlias: "Sonnet 别名", haikuAlias: "Haiku 别名", claudeSettingsAlert: "以下设置直接修改 ~/.claude/settings.json。重启 Claude CLI 生效。", writeToConfig: "写入配置", // Settings - Server port: "端口", uiVersion: "UI 版本", debugMode: "调试模式", environment: "运行环境", serverReadOnly: "服务器设置只读。修改 config.json 或 .env 并重启服务器以生效。", dangerZone: "危险区域 / 高级", reloadConfigTitle: "重载账号配置", reloadConfigDesc: "强制从磁盘重新读取 accounts.json", reload: "重载", // Config Specific primaryModel: "主模型", subAgentModel: "子代理模型", advancedOverrides: "默认模型覆盖 (高级)", opusModel: "Opus 模型", sonnetModel: "Sonnet 模型", haikuModel: "Haiku 模型", authToken: "认证令牌", saveConfig: "保存到 ~/.claude/settings.json", envVar: "环境变量", // New Keys systemName: "ANTIGRAVITY", systemDesc: "CLAUDE 代理系统", connectGoogleDesc: "连接 Google Workspace 账号以增加 API 配额。该账号将用于通过 Antigravity 代理 Claude 请求。", useCliCommand: "使用命令行", close: "关闭", requestVolume: "请求量", filter: "筛选", all: "全选", none: "清空", noDataTracked: "暂无追踪数据", selectFamilies: "选择要显示的系列", selectModels: "选择要显示的模型", noLogsMatch: "没有符合过滤条件的日志", connecting: "正在连接", main: "主菜单", system: "系统", refreshData: "刷新数据", connectionLost: "连接已断开", lastUpdated: "最后更新", grepLogs: "过滤日志...", noMatchingModels: "没有匹配的模型", typeToSearch: "输入以搜索或选择...", or: "或", refreshingAccount: "正在刷新 {email}...", refreshedAccount: "已完成刷新 {email}", refreshFailed: "刷新失败", accountToggled: "账号 {email} 已{status}", toggleFailed: "切换失败", reauthenticating: "正在重新认证 {email}...", authUrlFailed: "获取认证链接失败", deletedAccount: "已删除 {email}", deleteFailed: "删除失败", accountsReloaded: "账号配置已重载", reloadFailed: "重载失败", claudeConfigSaved: "Claude 配置已保存", saveConfigFailed: "保存配置失败", claudeActive: "Claude 活跃", claudeEmpty: "Claude 耗尽", geminiActive: "Gemini 活跃", geminiEmpty: "Gemini 耗尽", fix: "修复", synced: "已同步", syncing: "正在同步...", // Additional reloading: "正在重载...", reloaded: "已重载", lines: "行", enabledSeeLogs: "已启用 (见日志)", production: "生产环境", configSaved: "配置已保存", enterPassword: "请输入 Web UI 密码:", ready: "就绪", depleted: "已耗尽", timeH: "时", timeM: "分", familyClaude: "Claude 系列", familyGemini: "Gemini 系列", familyOther: "其他系列", enabledStatus: "已启用", disabledStatus: "已禁用", logLevelInfo: "信息", logLevelSuccess: "成功", logLevelWarn: "警告", logLevelError: "错误", totalColon: "总计:", todayColon: "今日:", hour1Colon: "1小时:", smart: "智能选择", smartTitle: "自动选择过去 24 小时最常用的 5 个模型", activeCount: "{count} 活跃", allCaps: "全部", claudeCaps: "CLAUDE", geminiCaps: "GEMINI", modelMapping: "映射 (目标模型 ID)", systemInfo: "系统信息", refresh: "刷新", runtimeConfig: "运行时配置", debugDesc: "启用详细日志记录 (见运行日志)", networkRetry: "网络重试设置", maxRetries: "最大重试次数", retryBaseDelay: "重试基础延迟 (毫秒)", retryMaxDelay: "重试最大延迟 (毫秒)", persistTokenCache: "持久化令牌缓存", persistTokenDesc: "将 OAuth 令牌保存到磁盘以实现快速重启", rateLimiting: "账号限流与超时", defaultCooldown: "默认冷却时间", maxWaitThreshold: "最大等待阈值 (粘性会话)", maxWaitDesc: "粘性账号在失败或切换前等待重置的最长时间。", saveConfigServer: "保存配置", serverRestartAlert: "部分更改可能需要重启服务器。配置已保存至 {path}", changePassword: "修改 WebUI 密码", changePasswordDesc: "更新访问此仪表盘的密码", currentPassword: "当前密码", newPassword: "新密码", confirmNewPassword: "确认新密码", passwordEmptyDesc: "如果未设置密码请留空", passwordLengthDesc: "至少 6 个字符", passwordConfirmDesc: "请再次输入新密码", cancel: "取消", passwordsNotMatch: "密码不匹配", passwordTooShort: "密码至少需要 6 个字符", } }, // Toast Messages toast: null, t(key, params = {}) { let str = this.translations[this.lang][key] || key; if (typeof str === 'string') { Object.keys(params).forEach(p => { str = str.replace(`{${p}}`, params[p]); }); } return str; }, setLang(l) { this.lang = l; localStorage.setItem('app_lang', l); }, showToast(message, type = 'info') { const id = Date.now(); this.toast = { message, type, id }; setTimeout(() => { if (this.toast && this.toast.id === id) this.toast = null; }, 3000); } }); });