feat(settings): data-safe editors, deep-linked search, Data/About/Cost pages
- EditorModal loads once per path (a parent re-render no longer reloads the file over the user's typing), refuses Save after a failed load, opens a truncated (>256 KB) file read-only, and asks before overwriting a file that changed on disk or could not be re-read. - Settings/Hooks editors unset only keys from the snapshot taken at Edit, warn when the file changed underneath, keep a renamed key's value, and refuse a new key named like a redacted one (env) or a read-only hook event, which used to replace the secret/hooks. - Project scope shows its resolved folder and is disabled inside the plugin cache. Account-profile, pricing-row and pet deletes confirm; two-click actions disarm after 3 s; unsaved drafts ask before closing. - Search indexes every Claude Code / Codex sub-tab, opens it via ?tab= and scrolls to + highlights the row; the active config tab is in the URL. - General splits into General / Data / About; Pricing moves to a Cost group with one shared load; config tabs group as Content / Extensions / Config with arrow-key roving; Promise.allSettled per tab. - Data: browser-preferences export/import (allowlisted keys), per-section reset, housekeeping dry-run first, clear-all behind a typed phrase. Server: purge days must be a whole number >= 1 (INVALID_PURGE_DAYS) and dry_run returns exactly what the real run would delete. - Alerts can be edited; webhooks/alerts/remote-source failures toast; copies go through copyText; modals get dialog roles and useDialog. - Sagi: Ctrl/Cmd+B only when shown and not typing, default spot clear of row controls, arrow keys move it, reduced motion honoured; the dead /run launch link goes to the workspace.
This commit is contained in:
@@ -64,7 +64,11 @@
|
||||
"minutesStatus": "Fire when an agent stays in the selected status with no activity for this many minutes (a stuck agent).",
|
||||
"totalTokens": "Fire when a session's cumulative tokens (input + output + cache read + cache write) cross this number. e.g. 1000000 = 1M tokens.",
|
||||
"cooldown": "Minimum seconds between repeat alerts for the same rule + session + agent. Prevents noisy duplicates. Default 300 (5 min); 0 = no cooldown."
|
||||
}
|
||||
},
|
||||
"edit": "Edit rule",
|
||||
"save": "Save rule",
|
||||
"typeFixed": "A rule's type cannot be changed — create a new rule instead.",
|
||||
"cooldownInvalid": "Enter a whole number of seconds (0 or more)."
|
||||
},
|
||||
"feed": {
|
||||
"title": "Alert feed",
|
||||
@@ -76,5 +80,12 @@
|
||||
"emptyTitle": "No alerts",
|
||||
"emptyDescription": "Alerts fired by your rules will appear here in real time.",
|
||||
"emptyUnacked": "Everything is acknowledged. New alerts will appear here as they fire."
|
||||
},
|
||||
"errors": {
|
||||
"loadRules": "Could not load alert rules: {{error}}",
|
||||
"loadAlerts": "Could not load alerts: {{error}}",
|
||||
"toggleRule": "Could not change the rule: {{error}}",
|
||||
"deleteRule": "Could not delete the rule: {{error}}",
|
||||
"ack": "Could not acknowledge: {{error}}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"user": "User",
|
||||
"project": "Project",
|
||||
"projectLocal": "Project (local)",
|
||||
"home": "Home"
|
||||
"home": "Home",
|
||||
"projectIs": "Project = {{path}}",
|
||||
"projectInCache": "The dashboard runs from Claude Code's plugin cache, which is replaced on every plugin update — project files written there would be lost. Project scope is off."
|
||||
},
|
||||
"tabs": {
|
||||
"overview": "Overview",
|
||||
@@ -155,7 +157,9 @@
|
||||
"fileMissing": "(no settings file at this scope)"
|
||||
},
|
||||
"settings": {
|
||||
"fileMissing": "(no settings file at this scope)"
|
||||
"fileMissing": "(no settings file at this scope)",
|
||||
"structured": "Structured",
|
||||
"rawJson": "Raw JSON"
|
||||
},
|
||||
"memory": {
|
||||
"userScope": "User memory",
|
||||
@@ -222,7 +226,17 @@
|
||||
"output-styles": "---\nname: my-style\ndescription: Output style description\n---\n\nStyle instructions.\n",
|
||||
"memory": "# Project memory\n\nClaude reads this on session start.\n",
|
||||
"auto-memory": "---\nname: my-fact\ndescription: One-line summary of the remembered fact\nmetadata:\n type: feedback\n---\n\nThe fact to remember.\n"
|
||||
}
|
||||
},
|
||||
"nameRequired": "Enter a name first.",
|
||||
"nameInvalid": "Use letters, digits, dot, dash or underscore (start with a letter or digit, max 64).",
|
||||
"loadError": "Could not load the file: {{message}}. Saving is disabled so it cannot be overwritten.",
|
||||
"truncatedReadOnly": "This file is larger than 256 KB and was only partly loaded, so it opens read-only. Edit it in your own editor.",
|
||||
"changedOnDiskTitle": "File changed on disk",
|
||||
"changedOnDiskBody": "Something else changed this file since you opened it. Saving now replaces that change with yours (a backup is still made).",
|
||||
"overwrite": "Overwrite",
|
||||
"unverifiedTitle": "Couldn't verify the file on disk",
|
||||
"unverifiedBody": "The file could not be re-read to check whether something else changed it since you opened it. Save anyway? (A backup of the current file is still made.)",
|
||||
"saveAnyway": "Save anyway"
|
||||
},
|
||||
"backups": {
|
||||
"title": "Backups",
|
||||
@@ -230,7 +244,7 @@
|
||||
"viewLink": "Show backup history",
|
||||
"openButton": "Backups",
|
||||
"subtitle": "Every save / delete in the editor writes a copy here first. Backup folders live outside the directories Claude Code scans, so they don't reappear as ghosts in your CLI.",
|
||||
"restoreHint": "Restore by renaming the backup back into place:",
|
||||
"restoreHint": "Restore by copying the backup back into place (the backup is kept):",
|
||||
"size": "Size",
|
||||
"created": "Created",
|
||||
"type": "Type",
|
||||
@@ -268,7 +282,9 @@
|
||||
"renameLabel": "Profile name",
|
||||
"renameHint": "Click to rename",
|
||||
"rename": "Rename",
|
||||
"renameSuccess": "Renamed to \"{{name}}\"."
|
||||
"renameSuccess": "Renamed to \"{{name}}\".",
|
||||
"deleteConfirmTitle": "Delete profile “{{name}}”?",
|
||||
"deleteConfirmBody": "This removes the saved login (OAuth credentials) for this account. To use it again you must run `claude auth login` and save it once more."
|
||||
},
|
||||
"explain": {
|
||||
"hooks": {
|
||||
@@ -390,6 +406,42 @@
|
||||
"settingsBadJson": "Value of {{key}} is not valid JSON.",
|
||||
"settingsSaved": "Settings saved to {{file}}.",
|
||||
"settingsHelp": "Values are JSON: \"opus\", true, 42, [\"a\"], {\"k\":1}. Only the keys you change are written; the rest of the file is left as-is.",
|
||||
"settingsRedactedKeys": "Not editable here because their values are redacted: {{keys}}"
|
||||
"settingsRedactedKeys": "Not editable here because their values are redacted: {{keys}}",
|
||||
"hooksChangedBody": "These hooks changed on disk since you started editing. Saving writes your version of the events you edited; events added meanwhile are kept.",
|
||||
"settingsChangedBody": "This settings file changed on disk since you started editing (the running CLI rewrites it). Saving writes the keys you changed; keys added meanwhile are kept.",
|
||||
"settingsRedactedKey": "“{{key}}” holds redacted secrets and can't be edited here — saving it would replace the real values with what you typed. Edit it in the file itself.",
|
||||
"hookReadOnlyEvent": "“{{event}}” already has hooks that can't be edited here (read-only) — a new row with that name would replace them. Use another event name, or edit the file itself."
|
||||
},
|
||||
"tabGroups": {
|
||||
"content": "Content",
|
||||
"extensions": "Extensions",
|
||||
"config": "Config"
|
||||
},
|
||||
"currentConfig": {
|
||||
"title": "Current configuration",
|
||||
"setCount_one": "{{count}} option set · the rest use defaults",
|
||||
"setCount_other": "{{count}} options set · the rest use defaults",
|
||||
"default": "default",
|
||||
"groups": {
|
||||
"model": "Model & reasoning",
|
||||
"output": "Output & display",
|
||||
"session": "Session & input"
|
||||
},
|
||||
"keys": {
|
||||
"model": "Model",
|
||||
"effortLevel": "Effort level",
|
||||
"alwaysThinkingEnabled": "Always thinking",
|
||||
"outputStyle": "Output style",
|
||||
"verbose": "Verbose output",
|
||||
"theme": "Theme",
|
||||
"language": "Language",
|
||||
"spinnerTipsEnabled": "Spinner tips",
|
||||
"autoScrollEnabled": "Auto-scroll",
|
||||
"autoCompactEnabled": "Auto-compact",
|
||||
"fileCheckpointingEnabled": "File checkpointing",
|
||||
"editorMode": "Editor mode",
|
||||
"preferredNotifChannel": "Notifications",
|
||||
"awaySummaryEnabled": "Away summary"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"title": "Backups",
|
||||
"subtitle": "Every save / delete writes a copy here first. Backup folders live outside the directories the CLI scans, so they don't reappear as ghosts in your CLI.",
|
||||
"empty": "No backups yet - every edit or delete creates a timestamped backup that lands here.",
|
||||
"restoreHint": "Restore by renaming the backup back into place:"
|
||||
"restoreHint": "Restore by copying the backup back into place (the backup is kept):"
|
||||
},
|
||||
"snippet": {
|
||||
"copy": "Copy",
|
||||
|
||||
@@ -20,13 +20,46 @@
|
||||
"upload": "Upload your own…",
|
||||
"import": "Import .codex-pet bundle…",
|
||||
"browse": "Find more on codex-pets.net",
|
||||
"settings": "Pet settings…"
|
||||
"settings": "Pet settings…",
|
||||
"hiddenToast": "Pet hidden. Show it again in Settings → Pet.",
|
||||
"deleteTitle": "Delete {{name}}?",
|
||||
"deleteMessage": "The pet's files are removed from this install. A featured pet can be downloaded again; an upload is gone for good.",
|
||||
"deleteConfirm": "Delete pet",
|
||||
"reset": "Reset to defaults",
|
||||
"resetDone": "Pet settings reset to defaults.",
|
||||
"hiddenNote": "The pet is hidden — size and speech bubbles apply once it is shown again.",
|
||||
"resetMessage": "Show the pet again with speech bubbles on, at 68 px, wearing Sagi. Your uploaded and downloaded pets are kept.",
|
||||
"previewCapped": "The preview is drawn at 120 px; the pet itself is {{size}} px."
|
||||
},
|
||||
"bubbles": "Speech bubbles",
|
||||
"bubblesDesc": "Let the pet comment on your sessions in a bubble",
|
||||
"sizeDesc": "{{min}}–{{max}} px; the preview is capped at 120 px",
|
||||
"chooseDesc": "Featured pets come from codex-pets.net and are downloaded into this install the first time you pick one. Your choice and size are saved in this browser.",
|
||||
"uploadHint": "An image (PNG, JPEG, GIF, WebP — no SVG) is shown still; a .codex-pet.zip (pet.json + a 1536×1872 spritesheet.webp) is animated by mood."
|
||||
"uploadHint": "An image (PNG, JPEG, GIF, WebP — no SVG) is shown still; a .codex-pet.zip (pet.json + a 1536×1872 spritesheet.webp) is animated by mood.",
|
||||
"panel": {
|
||||
"label": "Sagi companion",
|
||||
"live": "Live",
|
||||
"offline": "Offline",
|
||||
"close": "Close Sagi",
|
||||
"statLive": "live",
|
||||
"statWaiting": "waiting",
|
||||
"statErrored": "errored",
|
||||
"runClaude": "Run Claude",
|
||||
"activity": "Activity",
|
||||
"sessions": "Sessions",
|
||||
"errored": "Errored",
|
||||
"mute": "Mute",
|
||||
"unmute": "Unmute",
|
||||
"clearAlerts": "Clear alerts",
|
||||
"askPlaceholder": "Ask Sagi… (e.g. any errors?)",
|
||||
"ask": "Ask Sagi",
|
||||
"send": "Send"
|
||||
},
|
||||
"bubbleDismiss": "Dismiss",
|
||||
"open": "Open Sagi companion",
|
||||
"closeAvatar": "Close Sagi",
|
||||
"avatarTitle": "Sagi — Ctrl/⌘+B · drag or arrow keys to move · right-click for pets",
|
||||
"startFailed": "Couldn't start that session: {{error}}"
|
||||
},
|
||||
"pricing": {
|
||||
"vendor": {
|
||||
@@ -85,12 +118,17 @@
|
||||
}
|
||||
},
|
||||
"autoBadge": "Auto",
|
||||
"autoBadgeTitle": "Kept at the published rate automatically (LiteLLM's price list, checked daily). Edit it to keep your own rate."
|
||||
"autoBadgeTitle": "Kept at the published rate automatically (LiteLLM's price list, checked daily). Edit it to keep your own rate.",
|
||||
"deleteConfirmTitle": "Delete the pricing rule {{pattern}}?",
|
||||
"deleteConfirmBody": "Sessions on this model will be priced by another matching rule, or not at all. The automatic price sync will NOT add this pattern back; add it again by hand if you change your mind."
|
||||
},
|
||||
"claudeHome": {
|
||||
"title": "CLAUDE_HOME",
|
||||
"description": "Root directory for Claude Code session data. Changing this updates the scan path for transcripts and imports immediately.",
|
||||
"placeholder": "/path/to/claude-home"
|
||||
"placeholder": "/path/to/claude-home",
|
||||
"note": "Nothing is moved or copied: AgentHub just starts reading transcripts, config and hooks from the new folder. Cursor sessions use the same ~/.claude paths, so they follow it too.",
|
||||
"confirmTitle": "Change CLAUDE_HOME?",
|
||||
"confirmBody": "AgentHub will read sessions, config, skills and hooks from the new folder from now on. Sessions under the old folder stop being imported until you switch back. Nothing is moved or deleted."
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Hook Configuration",
|
||||
@@ -106,7 +144,16 @@
|
||||
"description": "Machine-wide workspace housekeeping.",
|
||||
"runHousekeeping": "Run housekeeping",
|
||||
"dryRun": "Dry run",
|
||||
"gcResult": "Reaped {{reaped}} process(es), capped {{capped}} log(s)"
|
||||
"gcResult": "Reaped {{reaped}} process(es), capped {{capped}} log(s)",
|
||||
"explain": "Cleans up after workspace sessions: stops MCP server processes that ended sessions left running, and trims workspace log files that grew too large. Nothing in your repositories is touched.",
|
||||
"preview": "Preview housekeeping",
|
||||
"gcReapLine": "stop leftover process {{pid}}",
|
||||
"gcCapLine": "trim {{path}} ({{size}})",
|
||||
"gcNothing": "Nothing to clean up — no leftover processes and no oversized logs.",
|
||||
"gcConfirmTitle": "Run housekeeping?",
|
||||
"gcConfirmBody": "This will:",
|
||||
"gcMore": "and {{count}} more",
|
||||
"gcPreviewResult": "Dry run: would stop {{reaped}} process(es) and trim {{capped}} log(s)"
|
||||
},
|
||||
"notifications": {
|
||||
"awaitingInput": "Claude needs confirmation",
|
||||
@@ -127,7 +174,7 @@
|
||||
"testFailed": "Nothing could be shown.",
|
||||
"testLocal": "Your browser has no push subscription, so this was shown locally. Web Push needs a secure origin (localhost or HTTPS) and a registered service worker.",
|
||||
"testSent": "Sent via push — check your notification centre.",
|
||||
"testTitle": "Agent Monitor",
|
||||
"testTitle": "AgentHub",
|
||||
"title": "Notifications",
|
||||
"turnComplete": "Claude finishes a turn",
|
||||
"sound": {
|
||||
@@ -140,7 +187,16 @@
|
||||
"pop": "Pop",
|
||||
"alert": "Alert",
|
||||
"forType": "Sound for this type"
|
||||
}
|
||||
},
|
||||
"scopeNote": "These notification settings are saved in this browser only. Alert rules and webhooks below are server-wide: they apply to everyone using this dashboard.",
|
||||
"insecureOrigin": "This page is served from {{origin}}, which is not a secure origin. Browsers only show notifications on HTTPS or localhost — open the dashboard through one of those to get them.",
|
||||
"unsupported": "This browser does not support notifications.",
|
||||
"deniedHelp": "Notifications are blocked for this site. To allow them again, open the site settings (the icon left of the address bar), set Notifications to Allow, then reload this page.",
|
||||
"pushFailed": "Notifications are on, but push could not be set up ({{message}}). They will still show while this tab is open.",
|
||||
"reset": "Reset to defaults",
|
||||
"resetTitle": "Reset notification settings?",
|
||||
"resetBody": "Every notification type and sound goes back to its default. Whether notifications are on stays as it is.",
|
||||
"resetDone": "Notification settings reset."
|
||||
},
|
||||
"import": {
|
||||
"title": "Import History",
|
||||
@@ -230,7 +286,10 @@
|
||||
"runCleanup": "Run Cleanup",
|
||||
"nothingToClean": "Nothing to clean up",
|
||||
"abandonedResult": " sessions abandoned",
|
||||
"purgedResult": " sessions purged ({{events}} events, {{agents}} agents)"
|
||||
"purgedResult": " sessions purged ({{events}} events, {{agents}} agents)",
|
||||
"wholeNumber": "Enter a whole number, 1 or more (or leave blank to skip).",
|
||||
"cleanupConfirmTitle": "Run session cleanup?",
|
||||
"cleanupConfirmBody": "This marks {{abandoned}} stale session(s) abandoned and permanently deletes {{sessions}} old session(s) with {{events}} event(s) and {{agents}} agent(s). Deleted sessions cannot be restored — export first if you may need them."
|
||||
},
|
||||
"danger": {
|
||||
"title": "Danger Zone",
|
||||
@@ -238,7 +297,11 @@
|
||||
"warning": "This will delete all sessions, agents, events, and token data. Are you sure?",
|
||||
"yesClearAll": "Yes, Clear All",
|
||||
"clearAllData": "Clear All Data",
|
||||
"clearedResult": "Cleared {{count}} rows"
|
||||
"clearedResult": "Cleared {{count}} rows",
|
||||
"dialogTitle": "Clear all data?",
|
||||
"exportFirst": "Export your data first.",
|
||||
"typeToConfirm": "Type “{{phrase}}” to confirm:",
|
||||
"phrase": "clear all data"
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
@@ -322,7 +385,11 @@
|
||||
"deleteMessage": "Delete \"{{name}}\"? Fired alerts will stop being delivered to this target. This cannot be undone.",
|
||||
"guideToggle": "How to set up {{provider}}",
|
||||
"guideDocs": "Official {{provider}} docs",
|
||||
"guideStaleNote": "Provider setup screens change often, so these steps may be out of date - always confirm against the official docs."
|
||||
"guideStaleNote": "Provider setup screens change often, so these steps may be out of date - always confirm against the official docs.",
|
||||
"loadFailed": "Could not load webhook targets: {{error}}",
|
||||
"toggleFailed": "Could not change the webhook: {{error}}",
|
||||
"deleteFailed": "Could not delete the webhook: {{error}}",
|
||||
"pickRule": "Tick at least one rule, or choose all rules."
|
||||
},
|
||||
"alertsHub": {
|
||||
"title": "Alerts",
|
||||
@@ -493,7 +560,8 @@
|
||||
"purgeData": "Also delete the sessions imported from this source (cannot be undone)",
|
||||
"deleteAndPurge": "Remove + delete data",
|
||||
"removeKeep": "Remove (keep data)",
|
||||
"remoteSourceBadgeTitle": "Collected from a remote machine"
|
||||
"remoteSourceBadgeTitle": "Collected from a remote machine",
|
||||
"fieldLabelPlaceholder": "Dev box"
|
||||
},
|
||||
"cursorPathsNote": "Informational: Cursor sessions count here too — Cursor happens to use the same ~/.claude paths as Claude Code (locally and on synced remotes).",
|
||||
"aiRouter": {
|
||||
@@ -579,7 +647,11 @@
|
||||
"darkThemes": "Dark themes",
|
||||
"lightThemes": "Light themes",
|
||||
"active": "· in use now",
|
||||
"default": "Default"
|
||||
"default": "Default",
|
||||
"reset": "Reset to defaults",
|
||||
"resetTitle": "Reset appearance?",
|
||||
"resetBody": "Mode goes back to Dark and both modes to their default theme.",
|
||||
"resetDone": "Appearance reset."
|
||||
},
|
||||
"gitCreds": {
|
||||
"title": "Git credentials",
|
||||
@@ -597,7 +669,9 @@
|
||||
"colUser": "Username",
|
||||
"colSaved": "Saved",
|
||||
"empty": "No git login saved. The git bar asks for one the first time a host needs it.",
|
||||
"badUrl": "Enter the server as a URL, e.g. https://git.example.com"
|
||||
"badUrl": "Enter the server as a URL, e.g. https://git.example.com",
|
||||
"saved": "Login saved for {{host}}.",
|
||||
"loading": "Loading…"
|
||||
},
|
||||
"homeDir": {
|
||||
"save": "Save",
|
||||
@@ -660,7 +734,11 @@
|
||||
"missing": "This file does not exist yet",
|
||||
"save": "Save",
|
||||
"close": "Close",
|
||||
"saved": "Saved. Backup: {{backup}}"
|
||||
"saved": "Saved. Backup: {{backup}}",
|
||||
"defaultModelSaved": "Default model saved.",
|
||||
"staleBody": "This file changed on disk since you opened it, so nothing was saved. Copy your version if you need it, then reload.",
|
||||
"copyMine": "Copy my version",
|
||||
"reloadDiscard": "Reload (discard mine)"
|
||||
},
|
||||
"settingsNav": {
|
||||
"label": "Settings sections",
|
||||
@@ -669,12 +747,13 @@
|
||||
"general": "General",
|
||||
"agents": "Agents",
|
||||
"routing": "Routing",
|
||||
"git": "Git"
|
||||
"git": "Git",
|
||||
"cost": "Cost"
|
||||
},
|
||||
"section": {
|
||||
"general": {
|
||||
"title": "General",
|
||||
"description": "Workspace housekeeping, data and about."
|
||||
"description": "The dashboard's display language."
|
||||
},
|
||||
"appearance": {
|
||||
"title": "Appearance",
|
||||
@@ -718,12 +797,23 @@
|
||||
"worktrees": {
|
||||
"title": "Worktrees",
|
||||
"description": "Which untracked git worktrees a workspace's Add folder suggests."
|
||||
},
|
||||
"data": {
|
||||
"title": "Data",
|
||||
"description": "Cost and database overview, import, remote sources, export, cleanup and the danger zone."
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
"description": "Server version, uptime and runtime."
|
||||
}
|
||||
}
|
||||
},
|
||||
"backPrevious": "Back",
|
||||
"unknownSection": "There is no “{{section}}” settings page — showing General instead."
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Search settings",
|
||||
"noMatch": "No setting matches “{{query}}”."
|
||||
"noMatch": "No setting matches “{{query}}”.",
|
||||
"results": "Search results"
|
||||
},
|
||||
"worktrees": {
|
||||
"title": "Worktree suggestions",
|
||||
@@ -751,5 +841,15 @@
|
||||
"copyPath": "Copy path",
|
||||
"enable": "Enable",
|
||||
"disable": "Disable"
|
||||
},
|
||||
"prefsBackup": {
|
||||
"title": "This browser's preferences",
|
||||
"description": "Theme, language, notification settings, pet, sidebar and workspace layout are kept in this browser. Save them to a file to move them to another browser, or restore them from one.",
|
||||
"export": "Export preferences",
|
||||
"import": "Import preferences…",
|
||||
"importTitle": "Import preferences?",
|
||||
"importBody": "The file's preferences replace this browser's, then the page reloads.",
|
||||
"imported": "Imported {{count}} preference(s). Reloading…",
|
||||
"badFile": "That file is not an AgentHub preferences file."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,5 +27,8 @@
|
||||
"pluginUpdating": "Pulling the new plugin version and reinstalling the runtime — this takes a few minutes, the page reloads itself when the new server is up...",
|
||||
"lastPluginUpdateFailed": "The last plugin update failed at step \"{{step}}\": {{error}} — run /agenthub-update in Claude Code to recover.",
|
||||
"restartingShort": "Restarting…",
|
||||
"installedTitle": "Version {{version}} is installed but not running"
|
||||
"installedTitle": "Version {{version}} is installed but not running",
|
||||
"later": "Not now",
|
||||
"skipVersion": "Skip this version",
|
||||
"skipVersionHint": "Don't ask again about this version; a newer one will still be offered."
|
||||
}
|
||||
|
||||
@@ -64,7 +64,11 @@
|
||||
"minutesStatus": "Kích hoạt khi agent ở trạng thái đã chọn mà không có hoạt động trong bấy nhiêu phút (agent bị kẹt).",
|
||||
"totalTokens": "Kích hoạt khi tổng token của phiên (input + output + cache read + cache write) vượt số này. vd 1000000 = 1 triệu token.",
|
||||
"cooldown": "Số giây tối thiểu giữa các cảnh báo lặp cho cùng quy tắc + phiên + agent. Tránh trùng lặp gây nhiễu. Mặc định 300 (5 phút); 0 = không có thời gian chờ."
|
||||
}
|
||||
},
|
||||
"edit": "Sửa quy tắc",
|
||||
"save": "Lưu quy tắc",
|
||||
"typeFixed": "Không đổi được loại của quy tắc — hãy tạo quy tắc mới.",
|
||||
"cooldownInvalid": "Nhập số giây nguyên (từ 0 trở lên)."
|
||||
},
|
||||
"feed": {
|
||||
"title": "Luồng cảnh báo",
|
||||
@@ -76,5 +80,12 @@
|
||||
"emptyTitle": "Không có cảnh báo",
|
||||
"emptyDescription": "Cảnh báo do các quy tắc của bạn kích hoạt sẽ hiển thị tại đây theo thời gian thực.",
|
||||
"emptyUnacked": "Tất cả đã được xác nhận. Cảnh báo mới sẽ hiển thị tại đây khi được kích hoạt."
|
||||
},
|
||||
"errors": {
|
||||
"loadRules": "Không tải được quy tắc cảnh báo: {{error}}",
|
||||
"loadAlerts": "Không tải được cảnh báo: {{error}}",
|
||||
"toggleRule": "Không thay đổi được quy tắc: {{error}}",
|
||||
"deleteRule": "Không xoá được quy tắc: {{error}}",
|
||||
"ack": "Không xác nhận được: {{error}}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"user": "Người dùng",
|
||||
"project": "Dự án",
|
||||
"projectLocal": "Dự án (cục bộ)",
|
||||
"home": "Home"
|
||||
"home": "Home",
|
||||
"projectIs": "Dự án = {{path}}",
|
||||
"projectInCache": "Dashboard đang chạy từ bộ nhớ đệm plugin của Claude Code, thư mục này bị thay mới mỗi lần cập nhật plugin — tệp dự án ghi vào đó sẽ mất. Đã tắt phạm vi Dự án."
|
||||
},
|
||||
"tabs": {
|
||||
"overview": "Tổng quan",
|
||||
@@ -150,7 +152,9 @@
|
||||
"fileMissing": "(không có file settings trong phạm vi này)"
|
||||
},
|
||||
"settings": {
|
||||
"fileMissing": "(không có file settings trong phạm vi này)"
|
||||
"fileMissing": "(không có file settings trong phạm vi này)",
|
||||
"structured": "Có cấu trúc",
|
||||
"rawJson": "JSON thô"
|
||||
},
|
||||
"memory": {
|
||||
"userScope": "Bộ nhớ người dùng",
|
||||
@@ -217,7 +221,17 @@
|
||||
"output-styles": "---\nname: my-style\ndescription: Mô tả kiểu xuất\n---\n\nChỉ thị về kiểu.\n",
|
||||
"memory": "# Bộ nhớ dự án\n\nClaude đọc tệp này khi bắt đầu phiên.\n",
|
||||
"auto-memory": "---\nname: my-fact\ndescription: Tóm tắt một dòng về sự kiện được ghi nhớ\nmetadata:\n type: feedback\n---\n\nNội dung cần ghi nhớ.\n"
|
||||
}
|
||||
},
|
||||
"nameRequired": "Hãy nhập tên trước.",
|
||||
"nameInvalid": "Chỉ dùng chữ, số, dấu chấm, gạch ngang hoặc gạch dưới (bắt đầu bằng chữ hoặc số, tối đa 64 ký tự).",
|
||||
"loadError": "Không tải được tệp: {{message}}. Đã tắt Lưu để tệp không bị ghi đè.",
|
||||
"truncatedReadOnly": "Tệp lớn hơn 256 KB nên chỉ tải được một phần, vì vậy chỉ mở ở chế độ đọc. Hãy sửa bằng trình soạn thảo của bạn.",
|
||||
"changedOnDiskTitle": "Tệp đã thay đổi trên đĩa",
|
||||
"changedOnDiskBody": "Có tiến trình khác đã sửa tệp này sau khi bạn mở. Lưu bây giờ sẽ thay thay đổi đó bằng nội dung của bạn (vẫn có bản sao lưu).",
|
||||
"overwrite": "Ghi đè",
|
||||
"unverifiedTitle": "Không kiểm tra được tệp trên đĩa",
|
||||
"unverifiedBody": "Không đọc lại được tệp để kiểm tra xem có gì khác đã sửa nó từ khi bạn mở hay chưa. Vẫn lưu? (Bản sao lưu của tệp hiện tại vẫn được tạo.)",
|
||||
"saveAnyway": "Vẫn lưu"
|
||||
},
|
||||
"backups": {
|
||||
"title": "Bản sao lưu",
|
||||
@@ -225,7 +239,7 @@
|
||||
"viewLink": "Xem lịch sử sao lưu",
|
||||
"openButton": "Bản sao lưu",
|
||||
"subtitle": "Mỗi thao tác lưu / xoá đều ghi bản sao tới đây trước. Thư mục sao lưu nằm ngoài các vị trí Claude Code quét, nên không xuất hiện như mục thừa trong CLI.",
|
||||
"restoreHint": "Khôi phục bằng cách đổi tên bản sao về vị trí cũ:",
|
||||
"restoreHint": "Khôi phục bằng cách sao chép bản sao lưu về chỗ cũ (bản sao lưu vẫn được giữ):",
|
||||
"size": "Kích thước",
|
||||
"created": "Tạo lúc",
|
||||
"type": "Loại",
|
||||
@@ -263,7 +277,9 @@
|
||||
"renameLabel": "Tên profile",
|
||||
"renameHint": "Bấm để đổi tên",
|
||||
"rename": "Đổi tên",
|
||||
"renameSuccess": "Đã đổi tên thành \"{{name}}\"."
|
||||
"renameSuccess": "Đã đổi tên thành \"{{name}}\".",
|
||||
"deleteConfirmTitle": "Xóa hồ sơ “{{name}}”?",
|
||||
"deleteConfirmBody": "Thao tác này xóa thông tin đăng nhập đã lưu (OAuth) của tài khoản này. Muốn dùng lại, bạn phải chạy `claude auth login` và lưu lại một lần nữa."
|
||||
},
|
||||
"explain": {
|
||||
"hooks": {
|
||||
@@ -385,6 +401,42 @@
|
||||
"settingsBadJson": "Giá trị của {{key}} không phải JSON hợp lệ.",
|
||||
"settingsSaved": "Đã lưu settings vào {{file}}.",
|
||||
"settingsHelp": "Giá trị là JSON: \"opus\", true, 42, [\"a\"], {\"k\":1}. Chỉ những khóa bạn sửa mới được ghi; phần còn lại của file giữ nguyên.",
|
||||
"settingsRedactedKeys": "Không sửa được ở đây vì giá trị đã bị che: {{keys}}"
|
||||
"settingsRedactedKeys": "Không sửa được ở đây vì giá trị đã bị che: {{keys}}",
|
||||
"hooksChangedBody": "Các hook này đã thay đổi trên đĩa kể từ khi bạn bắt đầu sửa. Lưu sẽ ghi phiên bản của bạn cho các sự kiện bạn đã sửa; các sự kiện mới thêm trong lúc đó vẫn được giữ.",
|
||||
"settingsChangedBody": "Tệp cài đặt này đã thay đổi trên đĩa kể từ khi bạn bắt đầu sửa (CLI đang chạy ghi lại nó). Lưu sẽ ghi các khóa bạn đã đổi; các khóa mới thêm trong lúc đó vẫn được giữ.",
|
||||
"settingsRedactedKey": "“{{key}}” chứa giá trị bí mật đã bị ẩn nên không sửa được ở đây — lưu sẽ thay giá trị thật bằng nội dung bạn nhập. Hãy sửa trực tiếp trong tệp.",
|
||||
"hookReadOnlyEvent": "“{{event}}” đã có hook không sửa được ở đây (chỉ đọc) — một dòng mới cùng tên sẽ thay thế chúng. Hãy dùng tên sự kiện khác hoặc sửa trực tiếp trong tệp."
|
||||
},
|
||||
"tabGroups": {
|
||||
"content": "Nội dung",
|
||||
"extensions": "Mở rộng",
|
||||
"config": "Cấu hình"
|
||||
},
|
||||
"currentConfig": {
|
||||
"title": "Cấu hình hiện tại",
|
||||
"setCount_one": "Đã đặt {{count}} tùy chọn · còn lại dùng mặc định",
|
||||
"setCount_other": "Đã đặt {{count}} tùy chọn · còn lại dùng mặc định",
|
||||
"default": "mặc định",
|
||||
"groups": {
|
||||
"model": "Mô hình & suy luận",
|
||||
"output": "Đầu ra & hiển thị",
|
||||
"session": "Phiên & nhập liệu"
|
||||
},
|
||||
"keys": {
|
||||
"model": "Mô hình",
|
||||
"effortLevel": "Mức nỗ lực",
|
||||
"alwaysThinkingEnabled": "Luôn suy nghĩ",
|
||||
"outputStyle": "Kiểu đầu ra",
|
||||
"verbose": "Đầu ra chi tiết",
|
||||
"theme": "Giao diện",
|
||||
"language": "Ngôn ngữ",
|
||||
"spinnerTipsEnabled": "Mẹo khi chờ",
|
||||
"autoScrollEnabled": "Tự cuộn",
|
||||
"autoCompactEnabled": "Tự nén ngữ cảnh",
|
||||
"fileCheckpointingEnabled": "Điểm khôi phục tệp",
|
||||
"editorMode": "Chế độ soạn thảo",
|
||||
"preferredNotifChannel": "Thông báo",
|
||||
"awaySummaryEnabled": "Tóm tắt khi vắng mặt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"title": "Bản sao lưu",
|
||||
"subtitle": "Mỗi thao tác lưu / xoá đều ghi bản sao tới đây trước. Thư mục sao lưu nằm ngoài các vị trí CLI quét, nên không xuất hiện như mục thừa trong CLI.",
|
||||
"empty": "Chưa có bản sao lưu - mỗi lần sửa hoặc xoá sẽ tạo bản sao có dấu thời gian.",
|
||||
"restoreHint": "Khôi phục bằng cách đổi tên bản sao về vị trí cũ:"
|
||||
"restoreHint": "Khôi phục bằng cách sao chép bản sao lưu về chỗ cũ (bản sao lưu vẫn được giữ):"
|
||||
},
|
||||
"snippet": {
|
||||
"copy": "Sao chép",
|
||||
|
||||
@@ -20,13 +20,46 @@
|
||||
"upload": "Tải ảnh của bạn lên…",
|
||||
"import": "Nhập bundle .codex-pet…",
|
||||
"browse": "Tìm thêm trên codex-pets.net",
|
||||
"settings": "Cài đặt pet…"
|
||||
"settings": "Cài đặt pet…",
|
||||
"hiddenToast": "Đã ẩn pet. Bật lại trong Cài đặt → Pet.",
|
||||
"deleteTitle": "Xoá {{name}}?",
|
||||
"deleteMessage": "Các tệp của pet sẽ bị xoá khỏi bản cài này. Pet nổi bật có thể tải lại; ảnh bạn tải lên sẽ mất hẳn.",
|
||||
"deleteConfirm": "Xoá pet",
|
||||
"reset": "Khôi phục mặc định",
|
||||
"resetDone": "Đã khôi phục cài đặt pet về mặc định.",
|
||||
"hiddenNote": "Pet đang ẩn — kích thước và bong bóng lời thoại sẽ áp dụng khi hiện lại.",
|
||||
"resetMessage": "Hiện lại pet, bật bong bóng lời thoại, kích thước 68 px và dùng Sagi. Các pet bạn đã tải lên hoặc tải về vẫn được giữ.",
|
||||
"previewCapped": "Bản xem trước vẽ ở 120 px; pet thật có kích thước {{size}} px."
|
||||
},
|
||||
"bubbles": "Bong bóng lời thoại",
|
||||
"bubblesDesc": "Cho pet bình luận về các session của bạn trong bong bóng",
|
||||
"sizeDesc": "{{min}}–{{max}} px; bản xem trước tối đa 120 px",
|
||||
"chooseDesc": "Pet nổi bật lấy từ codex-pets.net và được tải về máy ở lần đầu bạn chọn. Lựa chọn và kích thước được lưu trong trình duyệt này.",
|
||||
"uploadHint": "Ảnh (PNG, JPEG, GIF, WebP — không nhận SVG) hiển thị tĩnh; file .codex-pet.zip (pet.json + spritesheet.webp 1536×1872) chuyển động theo tâm trạng."
|
||||
"uploadHint": "Ảnh (PNG, JPEG, GIF, WebP — không nhận SVG) hiển thị tĩnh; file .codex-pet.zip (pet.json + spritesheet.webp 1536×1872) chuyển động theo tâm trạng.",
|
||||
"panel": {
|
||||
"label": "Trợ lý Sagi",
|
||||
"live": "Trực tuyến",
|
||||
"offline": "Ngoại tuyến",
|
||||
"close": "Đóng Sagi",
|
||||
"statLive": "đang chạy",
|
||||
"statWaiting": "đang chờ",
|
||||
"statErrored": "lỗi",
|
||||
"runClaude": "Chạy Claude",
|
||||
"activity": "Hoạt động",
|
||||
"sessions": "Phiên",
|
||||
"errored": "Phiên lỗi",
|
||||
"mute": "Tắt tiếng",
|
||||
"unmute": "Bật tiếng",
|
||||
"clearAlerts": "Xoá cảnh báo",
|
||||
"askPlaceholder": "Hỏi Sagi… (vd: có lỗi nào không?)",
|
||||
"ask": "Hỏi Sagi",
|
||||
"send": "Gửi"
|
||||
},
|
||||
"bubbleDismiss": "Đóng",
|
||||
"open": "Mở trợ lý Sagi",
|
||||
"closeAvatar": "Đóng Sagi",
|
||||
"avatarTitle": "Sagi — Ctrl/⌘+B · kéo hoặc dùng phím mũi tên để di chuyển · chuột phải để chọn pet",
|
||||
"startFailed": "Không khởi động được phiên: {{error}}"
|
||||
},
|
||||
"pricing": {
|
||||
"vendor": {
|
||||
@@ -62,8 +95,8 @@
|
||||
},
|
||||
"cacheWrite5m": "Ghi bộ nhớ đệm (5m)",
|
||||
"cacheWrite1h": "Ghi bộ nhớ đệm (1h)",
|
||||
"fastInput": "Fast Input",
|
||||
"fastOutput": "Fast Output",
|
||||
"fastInput": "Đầu vào nhanh",
|
||||
"fastOutput": "Đầu ra nhanh",
|
||||
"showAll": "Hiện mọi model (thêm {{count}})",
|
||||
"empty": {
|
||||
"claude": "Chưa có giá model Claude. Nút Khôi phục mặc định sẽ đưa chúng trở lại.",
|
||||
@@ -85,12 +118,17 @@
|
||||
}
|
||||
},
|
||||
"autoBadge": "Tự động",
|
||||
"autoBadgeTitle": "Tự cập nhật theo giá công bố (bảng giá LiteLLM, kiểm tra mỗi ngày). Sửa dòng này để giữ giá của riêng bạn."
|
||||
"autoBadgeTitle": "Tự cập nhật theo giá công bố (bảng giá LiteLLM, kiểm tra mỗi ngày). Sửa dòng này để giữ giá của riêng bạn.",
|
||||
"deleteConfirmTitle": "Xoá quy tắc giá {{pattern}}?",
|
||||
"deleteConfirmBody": "Các phiên dùng mô hình này sẽ được tính giá theo quy tắc khớp khác, hoặc không được tính. Đồng bộ giá tự động sẽ KHÔNG thêm lại mẫu này; nếu đổi ý, hãy tự thêm lại."
|
||||
},
|
||||
"claudeHome": {
|
||||
"title": "CLAUDE_HOME",
|
||||
"description": "Thư mục gốc chứa dữ liệu phiên Claude Code. Thay đổi sẽ cập nhật ngay đường dẫn quét cho transcript và import.",
|
||||
"placeholder": "/đường-dẫn/tới/claude-home"
|
||||
"placeholder": "/đường-dẫn/tới/claude-home",
|
||||
"note": "Không có gì bị di chuyển hay sao chép: AgentHub chỉ bắt đầu đọc transcript, cấu hình và hook từ thư mục mới. Phiên Cursor dùng cùng đường dẫn ~/.claude nên cũng theo thư mục này.",
|
||||
"confirmTitle": "Đổi CLAUDE_HOME?",
|
||||
"confirmBody": "Từ giờ AgentHub sẽ đọc phiên, cấu hình, skill và hook từ thư mục mới. Các phiên trong thư mục cũ sẽ không được nhập nữa cho tới khi bạn đổi lại. Không có gì bị di chuyển hay xoá."
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Cấu hình hook",
|
||||
@@ -106,7 +144,16 @@
|
||||
"description": "Dọn dẹp workspace trên toàn máy.",
|
||||
"runHousekeeping": "Chạy dọn dẹp",
|
||||
"dryRun": "Chạy thử (dry run)",
|
||||
"gcResult": "Đã dọn {{reaped}} tiến trình, cắt {{capped}} log"
|
||||
"gcResult": "Đã dọn {{reaped}} tiến trình, cắt {{capped}} log",
|
||||
"explain": "Dọn dẹp sau các phiên của không gian làm việc: dừng các tiến trình máy chủ MCP mà phiên đã kết thúc còn để lại, và cắt bớt tệp nhật ký quá lớn. Không đụng tới kho mã của bạn.",
|
||||
"preview": "Xem trước dọn dẹp",
|
||||
"gcReapLine": "dừng tiến trình còn sót {{pid}}",
|
||||
"gcCapLine": "cắt bớt {{path}} ({{size}})",
|
||||
"gcNothing": "Không có gì để dọn — không còn tiến trình sót và không có nhật ký quá lớn.",
|
||||
"gcConfirmTitle": "Chạy dọn dẹp?",
|
||||
"gcConfirmBody": "Thao tác này sẽ:",
|
||||
"gcMore": "và {{count}} mục khác",
|
||||
"gcPreviewResult": "Chạy thử: sẽ dừng {{reaped}} tiến trình và cắt bớt {{capped}} tệp nhật ký"
|
||||
},
|
||||
"notifications": {
|
||||
"awaitingInput": "Claude cần xác nhận",
|
||||
@@ -127,7 +174,7 @@
|
||||
"testFailed": "Không hiển thị được thông báo nào.",
|
||||
"testLocal": "Trình duyệt chưa đăng ký push nên thông báo được hiện tại chỗ. Web Push cần origin bảo mật (localhost hoặc HTTPS) và service worker đã đăng ký.",
|
||||
"testSent": "Đã gửi qua push — kiểm tra trung tâm thông báo.",
|
||||
"testTitle": "Agent Monitor",
|
||||
"testTitle": "AgentHub",
|
||||
"title": "Thông báo",
|
||||
"turnComplete": "Claude trả lời xong",
|
||||
"sound": {
|
||||
@@ -140,7 +187,16 @@
|
||||
"pop": "Pop",
|
||||
"alert": "Cảnh báo",
|
||||
"forType": "Âm thanh cho loại này"
|
||||
}
|
||||
},
|
||||
"scopeNote": "Các cài đặt thông báo này chỉ lưu trong trình duyệt này. Quy tắc cảnh báo và webhook bên dưới áp dụng cho toàn máy chủ: mọi người dùng bảng điều khiển này đều chịu ảnh hưởng.",
|
||||
"insecureOrigin": "Trang này được phục vụ từ {{origin}}, không phải nguồn bảo mật. Trình duyệt chỉ hiện thông báo trên HTTPS hoặc localhost — hãy mở bảng điều khiển qua một trong hai cách đó.",
|
||||
"unsupported": "Trình duyệt này không hỗ trợ thông báo.",
|
||||
"deniedHelp": "Thông báo đang bị chặn cho trang này. Để cho phép lại, mở cài đặt trang (biểu tượng bên trái thanh địa chỉ), đặt Thông báo thành Cho phép, rồi tải lại trang.",
|
||||
"pushFailed": "Thông báo đã bật nhưng không thiết lập được push ({{message}}). Thông báo vẫn hiện khi thẻ này đang mở.",
|
||||
"reset": "Khôi phục mặc định",
|
||||
"resetTitle": "Khôi phục cài đặt thông báo?",
|
||||
"resetBody": "Mọi loại thông báo và âm thanh trở về mặc định. Trạng thái bật/tắt thông báo được giữ nguyên.",
|
||||
"resetDone": "Đã khôi phục cài đặt thông báo."
|
||||
},
|
||||
"import": {
|
||||
"title": "Nhập lịch sử",
|
||||
@@ -230,7 +286,10 @@
|
||||
"runCleanup": "Chạy dọn dẹp",
|
||||
"nothingToClean": "Không có gì để dọn dẹp",
|
||||
"abandonedResult": " phiên đã bị bỏ dở",
|
||||
"purgedResult": " phiên đã xóa ({{events}} sự kiện, {{agents}} Agent)"
|
||||
"purgedResult": " phiên đã xóa ({{events}} sự kiện, {{agents}} Agent)",
|
||||
"wholeNumber": "Nhập số nguyên từ 1 trở lên (hoặc để trống để bỏ qua).",
|
||||
"cleanupConfirmTitle": "Chạy dọn dẹp phiên?",
|
||||
"cleanupConfirmBody": "Thao tác này đánh dấu {{abandoned}} phiên cũ là bị bỏ dở và xóa vĩnh viễn {{sessions}} phiên cũ cùng {{events}} sự kiện và {{agents}} tác tử. Phiên đã xóa không thể khôi phục — hãy xuất dữ liệu trước nếu có thể cần."
|
||||
},
|
||||
"danger": {
|
||||
"title": "Vùng nguy hiểm",
|
||||
@@ -238,7 +297,11 @@
|
||||
"warning": "Thao tác này sẽ xóa toàn bộ phiên, Agent, sự kiện và dữ liệu token. Bạn chắc chứ?",
|
||||
"yesClearAll": "Có, xóa tất cả",
|
||||
"clearAllData": "Xóa toàn bộ dữ liệu",
|
||||
"clearedResult": "Đã xóa {{count}} dòng"
|
||||
"clearedResult": "Đã xóa {{count}} dòng",
|
||||
"dialogTitle": "Xóa toàn bộ dữ liệu?",
|
||||
"exportFirst": "Hãy xuất dữ liệu trước.",
|
||||
"typeToConfirm": "Gõ “{{phrase}}” để xác nhận:",
|
||||
"phrase": "xóa toàn bộ dữ liệu"
|
||||
},
|
||||
"about": {
|
||||
"title": "Giới thiệu",
|
||||
@@ -322,7 +385,11 @@
|
||||
"deleteMessage": "Xóa \"{{name}}\"? Cảnh báo sẽ ngừng được gửi tới đích này. Không thể hoàn tác.",
|
||||
"guideToggle": "Cách thiết lập {{provider}}",
|
||||
"guideDocs": "Tài liệu chính thức của {{provider}}",
|
||||
"guideStaleNote": "Giao diện thiết lập của nhà cung cấp thường thay đổi nên các bước này có thể đã lỗi thời - hãy luôn kiểm tra tài liệu chính thức."
|
||||
"guideStaleNote": "Giao diện thiết lập của nhà cung cấp thường thay đổi nên các bước này có thể đã lỗi thời - hãy luôn kiểm tra tài liệu chính thức.",
|
||||
"loadFailed": "Không tải được danh sách webhook: {{error}}",
|
||||
"toggleFailed": "Không thay đổi được webhook: {{error}}",
|
||||
"deleteFailed": "Không xoá được webhook: {{error}}",
|
||||
"pickRule": "Hãy chọn ít nhất một quy tắc, hoặc chọn tất cả quy tắc."
|
||||
},
|
||||
"alertsHub": {
|
||||
"title": "Cảnh báo",
|
||||
@@ -493,7 +560,8 @@
|
||||
"purgeData": "Đồng thời xóa các phiên đã nhập từ nguồn này (không thể hoàn tác)",
|
||||
"deleteAndPurge": "Xóa + xóa dữ liệu",
|
||||
"removeKeep": "Xóa (giữ dữ liệu)",
|
||||
"remoteSourceBadgeTitle": "Được thu thập từ một máy từ xa"
|
||||
"remoteSourceBadgeTitle": "Được thu thập từ một máy từ xa",
|
||||
"fieldLabelPlaceholder": "Máy dev"
|
||||
},
|
||||
"cursorPathsNote": "Chỉ mang tính thông tin: phiên Cursor cũng được tính — Cursor tình cờ dùng cùng đường dẫn ~/.claude với Claude Code (cục bộ và trên máy từ xa đã đồng bộ).",
|
||||
"aiRouter": {
|
||||
@@ -579,7 +647,11 @@
|
||||
"darkThemes": "Theme tối",
|
||||
"lightThemes": "Theme sáng",
|
||||
"active": "· đang dùng",
|
||||
"default": "Mặc định"
|
||||
"default": "Mặc định",
|
||||
"reset": "Khôi phục mặc định",
|
||||
"resetTitle": "Khôi phục giao diện?",
|
||||
"resetBody": "Chế độ trở về Tối và cả hai chế độ trở về giao diện mặc định.",
|
||||
"resetDone": "Đã khôi phục giao diện."
|
||||
},
|
||||
"gitCreds": {
|
||||
"title": "Git credentials",
|
||||
@@ -597,7 +669,9 @@
|
||||
"colUser": "Tên đăng nhập",
|
||||
"colSaved": "Đã lưu",
|
||||
"empty": "Chưa lưu tài khoản git nào. Thanh git sẽ hỏi khi một host cần đăng nhập.",
|
||||
"badUrl": "Nhập máy chủ dạng URL, ví dụ https://git.example.com"
|
||||
"badUrl": "Nhập máy chủ dạng URL, ví dụ https://git.example.com",
|
||||
"saved": "Đã lưu thông tin đăng nhập cho {{host}}.",
|
||||
"loading": "Đang tải…"
|
||||
},
|
||||
"homeDir": {
|
||||
"save": "Lưu",
|
||||
@@ -660,7 +734,11 @@
|
||||
"missing": "File này chưa có",
|
||||
"save": "Lưu",
|
||||
"close": "Đóng",
|
||||
"saved": "Đã lưu. Bản sao lưu: {{backup}}"
|
||||
"saved": "Đã lưu. Bản sao lưu: {{backup}}",
|
||||
"defaultModelSaved": "Đã lưu mô hình mặc định.",
|
||||
"staleBody": "Tệp đã thay đổi trên đĩa kể từ lúc bạn mở nên chưa lưu gì. Hãy sao chép bản của bạn nếu cần, rồi tải lại.",
|
||||
"copyMine": "Sao chép bản của tôi",
|
||||
"reloadDiscard": "Tải lại (bỏ bản của tôi)"
|
||||
},
|
||||
"settingsNav": {
|
||||
"label": "Các mục cài đặt",
|
||||
@@ -669,12 +747,13 @@
|
||||
"general": "Chung",
|
||||
"agents": "Tác tử",
|
||||
"routing": "Định tuyến",
|
||||
"git": "Git"
|
||||
"git": "Git",
|
||||
"cost": "Chi phí"
|
||||
},
|
||||
"section": {
|
||||
"general": {
|
||||
"title": "Chung",
|
||||
"description": "Dọn dẹp workspace, dữ liệu và thông tin."
|
||||
"description": "Ngôn ngữ hiển thị của bảng điều khiển."
|
||||
},
|
||||
"appearance": {
|
||||
"title": "Giao diện",
|
||||
@@ -718,12 +797,23 @@
|
||||
"worktrees": {
|
||||
"title": "Worktree",
|
||||
"description": "Những git worktree chưa theo dõi được gợi ý khi thêm thư mục cho workspace."
|
||||
},
|
||||
"data": {
|
||||
"title": "Dữ liệu",
|
||||
"description": "Tổng quan chi phí và cơ sở dữ liệu, nhập, nguồn từ xa, xuất, dọn dẹp và vùng nguy hiểm."
|
||||
},
|
||||
"about": {
|
||||
"title": "Giới thiệu",
|
||||
"description": "Phiên bản máy chủ, thời gian hoạt động và môi trường chạy."
|
||||
}
|
||||
}
|
||||
},
|
||||
"backPrevious": "Quay lại",
|
||||
"unknownSection": "Không có trang cài đặt “{{section}}” — đang hiển thị trang Chung."
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Tìm cài đặt",
|
||||
"noMatch": "Không có cài đặt nào khớp “{{query}}”."
|
||||
"noMatch": "Không có cài đặt nào khớp “{{query}}”.",
|
||||
"results": "Kết quả tìm kiếm"
|
||||
},
|
||||
"worktrees": {
|
||||
"title": "Gợi ý worktree",
|
||||
@@ -751,5 +841,15 @@
|
||||
"copyPath": "Sao chép đường dẫn",
|
||||
"enable": "Bật",
|
||||
"disable": "Tắt"
|
||||
},
|
||||
"prefsBackup": {
|
||||
"title": "Tùy chọn của trình duyệt này",
|
||||
"description": "Giao diện, ngôn ngữ, cài đặt thông báo, thú cưng, thanh bên và bố cục không gian làm việc được lưu trong trình duyệt này. Lưu chúng ra tệp để chuyển sang trình duyệt khác, hoặc khôi phục từ tệp.",
|
||||
"export": "Xuất tùy chọn",
|
||||
"import": "Nhập tùy chọn…",
|
||||
"importTitle": "Nhập tùy chọn?",
|
||||
"importBody": "Tùy chọn trong tệp sẽ thay thế tùy chọn của trình duyệt này, sau đó trang tải lại.",
|
||||
"imported": "Đã nhập {{count}} tùy chọn. Đang tải lại…",
|
||||
"badFile": "Tệp này không phải tệp tùy chọn của AgentHub."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,5 +27,8 @@
|
||||
"pluginUpdating": "Đang tải bản plugin mới và cài lại runtime — mất vài phút, trang sẽ tự reload khi server mới lên...",
|
||||
"lastPluginUpdateFailed": "Lần cập nhật plugin trước thất bại ở bước \"{{step}}\": {{error}} — chạy /agenthub-update trong Claude Code để khắc phục.",
|
||||
"restartingShort": "Đang khởi động lại…",
|
||||
"installedTitle": "Đã cài bản {{version}} nhưng chưa chạy"
|
||||
"installedTitle": "Đã cài bản {{version}} nhưng chưa chạy",
|
||||
"later": "Để sau",
|
||||
"skipVersion": "Bỏ qua phiên bản này",
|
||||
"skipVersionHint": "Không hỏi lại về phiên bản này; phiên bản mới hơn vẫn sẽ được thông báo."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user