a9c71cd905
Usage panel (status bar): - every account shows its plan (Claude subscriptionType, Codex chatgpt_plan_type, Cursor membershipType, Grok subscriptionTier) - new quota rows: Cursor CLI (cursor.com usage-summary), Antigravity (`agy --print /usage`, two model pools; AGENTHUB_AGY_USAGE=0 never runs agy), Grok Build, Kimi Code, OpenCode Go — each login read from the tool's own file, sent only to its own host while valid, never refreshed - in-flight quota reads are shared between tabs AI Tools catalog: Grok Build (`grok`) and Kimi Code (`kimi`) added; Gemini CLI, Hermes and OpenClaw removed. Also: Quit AgentHub (#65, `agenthub stop`), status-area icon, Add to Chat on an editor selection, Settings in three groups, JetBrains-style Changes panel (ticked files/hunks, ignore, blame, file history), terminal font. --no-verify: :3000 is taken by another dev server (lane-detect tests); both suites run by hand — server 2636/2639 (the 3 are :3000), client 1131/1131.
990 lines
48 KiB
JSON
990 lines
48 KiB
JSON
{
|
||
"title": "Settings",
|
||
"subtitle": "Manage appearance, AI tools, notifications and data",
|
||
"exportData": "Export Data",
|
||
"acrossSessions": "Across all tracked sessions",
|
||
"basedOnUsage": "Based on per-model token usage",
|
||
"sagi": {
|
||
"title": "Sagi companion",
|
||
"description": "A floating mascot that reacts to your live sessions.",
|
||
"enable": "Show Sagi",
|
||
"enableDesc": "Display the corner companion across the dashboard (⌘B to open)",
|
||
"pet": {
|
||
"title": "Pet",
|
||
"hide": "Hide pet",
|
||
"size": "Size",
|
||
"choose": "Choose pet",
|
||
"featuredBy": "By {{by}} on codex-pets.net — downloaded into this install on first pick",
|
||
"download": "Download",
|
||
"delete": "Delete {{name}}",
|
||
"upload": "Upload your own…",
|
||
"import": "Import .codex-pet bundle…",
|
||
"browse": "Find more on codex-pets.net",
|
||
"settings": "Pet settings…",
|
||
"hiddenToast": "Pet hidden. Show it again in Settings → Appearance.",
|
||
"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.",
|
||
"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": {
|
||
"claude": "Anthropic (Claude)",
|
||
"openai": "OpenAI (Codex)",
|
||
"google": "Google (Gemini)"
|
||
},
|
||
"title": "Model Pricing",
|
||
"description": "Rates per million tokens (USD). Use % as wildcard in patterns. Some models have a time-limited introductory rate (shown in violet); usage on or before its cutoff date is billed at that rate, and usage after it at the standard rate.",
|
||
"introNote": "Intro ${{input}}/${{output}} through {{until}}",
|
||
"introRatesTitle": "Introductory rates",
|
||
"introRatesHint": "Leave the date empty for no promo",
|
||
"introUntil": "Through (date)",
|
||
"introUntilInvalid": "Introductory cutoff must be a YYYY-MM-DD date",
|
||
"resetConfirm": "Confirm Reset",
|
||
"resetDefaults": "Reset Defaults",
|
||
"resetResult": "Reset to {{count}} default rules",
|
||
"addModel": "Add Model",
|
||
"pattern": "Pattern",
|
||
"validationRequired": "Pattern and display name are required",
|
||
"lastUpdated": "Last updated: ",
|
||
"tooltip": {
|
||
"title": "How model pricing works",
|
||
"howItWorks": "How it works",
|
||
"howItWorksBody": "When a session reports usage, the dashboard finds the first pricing rule whose pattern matches the model id and multiplies (input tokens / 1M) and (output tokens / 1M) by the rates below to compute cost. Rules are evaluated top-to-bottom - the first match wins.",
|
||
"patternsTitle": "Pattern syntax",
|
||
"patternsBody": "Patterns are SQL-style globs. % is a wildcard that matches any characters. For example: claude-opus-4-7% matches every model id that starts with claude-opus-4-7 (e.g. claude-opus-4-7, claude-opus-4-7-20260101). claude-%-haiku matches any haiku variant. An exact id like claude-sonnet-4-6 only matches itself.",
|
||
"apiPricing": "Reference only - API rates",
|
||
"apiPricingBody": "These are pay-as-you-go API rates. If you use Claude Code on a subscription plan (Pro, Max, Team, or Enterprise), your actual cost is a flat monthly fee, not per-token - so these figures will usually be higher than what you really pay. Treat the costs here as a usage estimate for reference, not a bill.",
|
||
"synced": "Prices are filled in automatically",
|
||
"syncedBody": "Every current Claude, OpenAI and Gemini model is priced from LiteLLM's public price list, checked once a day, as is any other model the moment a session uses it. Rows marked Auto follow that list when a rate changes; a row you edit becomes yours and is never touched again, and a row you delete stays deleted. Already-stored sessions keep the price that was applied at ingest time.",
|
||
"apiPricingOtherBody": "These are pay-as-you-go API rates. If you use this CLI on a subscription plan, your actual cost is a flat fee, not per-token - so these figures will usually be higher than what you really pay. Treat them as a usage estimate, not a bill."
|
||
},
|
||
"cacheWrite5m": "Cache Write (5m)",
|
||
"cacheWrite1h": "Cache Write (1h)",
|
||
"fastInput": "Fast Input",
|
||
"fastOutput": "Fast Output",
|
||
"showAll": "Show all models ({{count}} more)",
|
||
"empty": {
|
||
"claude": "No Claude model prices. Reset Defaults restores them.",
|
||
"openai": "No OpenAI model prices yet. They are added automatically from LiteLLM's price list once a Codex session uses a model, or add one yourself.",
|
||
"google": "No Gemini model prices yet. They are added automatically from LiteLLM's price list once an Antigravity session uses a model, or add one yourself."
|
||
},
|
||
"placeholders": {
|
||
"claude": {
|
||
"pattern": "claude-opus-4%",
|
||
"name": "Claude Opus 4"
|
||
},
|
||
"openai": {
|
||
"pattern": "gpt-5%",
|
||
"name": "GPT 5"
|
||
},
|
||
"google": {
|
||
"pattern": "gemini-3.8-flash%",
|
||
"name": "Gemini 3.8 Flash"
|
||
}
|
||
},
|
||
"autoBadge": "Auto",
|
||
"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",
|
||
"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",
|
||
"description": "Claude Code hooks forward events to the dashboard in real time.",
|
||
"allInstalled": "All hooks installed",
|
||
"incomplete": "Hooks incomplete",
|
||
"reinstall": "Reinstall Hooks",
|
||
"success": "Hooks installed successfully",
|
||
"failed": "Hook installation failed",
|
||
"plugin": "Provided by the agenthub plugin (its plugin.json), not settings.json"
|
||
},
|
||
"lanesSection": {
|
||
"title": "Workspaces",
|
||
"description": "Machine-wide workspace housekeeping.",
|
||
"runHousekeeping": "Run housekeeping",
|
||
"dryRun": "Dry run",
|
||
"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",
|
||
"blocked": "Permission blocked",
|
||
"description": "Browser notifications for important events. Requires permission.",
|
||
"disabledInfo": "Notifications are disabled - enable to get alerts for session events",
|
||
"enable": "Enable Browser Notifications",
|
||
"granted": "Permission granted",
|
||
"newSession": "New session starts",
|
||
"notifyWhen": "Notify me when...",
|
||
"required": "Permission required",
|
||
"sendTest": "Send Test Notification",
|
||
"sessionComplete": "Session completes",
|
||
"sessionError": "Session errors",
|
||
"subagentSpawned": "Subagent spawned",
|
||
"testBlocked": "The browser has not granted notification permission.",
|
||
"testBody": "Notifications are working!",
|
||
"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": "AgentHub",
|
||
"title": "Notifications",
|
||
"turnComplete": "Claude finishes a turn",
|
||
"sound": {
|
||
"title": "Sound",
|
||
"description": "Played with every notification shown. Each type below can pick its own.",
|
||
"preview": "Play",
|
||
"useDefault": "Default",
|
||
"none": "None",
|
||
"chime": "Chime",
|
||
"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",
|
||
"description": "Bring existing Claude Code sessions into the dashboard. Token counts, per-model cost, compactions, subagents, tool uses, and turn durations are reconstructed from the original JSONL transcripts - identical to how live sessions are captured.",
|
||
"accuracyNote": "Re-running is safe. Sessions are deduplicated by session ID, and compaction baselines ensure token totals never double-count.",
|
||
"supportedFiles": "Supported inputs: .jsonl, .meta.json, .zip, .tar, .tar.gz, .tgz, .gz",
|
||
"instructions": "How to gather your history",
|
||
"stepLocate": "1. Locate your Claude Code history",
|
||
"stepLocateBody": "Every Claude Code session is stored as a JSONL transcript under the projects folder. Each subfolder is named after the working directory where the session started (slashes replaced with dashes).",
|
||
"stepArchive": "2. Bundle it for transfer (optional)",
|
||
"stepArchiveBody": "To move history from another machine, archive the whole folder first, then copy it over (AirDrop, scp, USB, cloud storage):",
|
||
"stepChoose": "3. Pick an import mode below",
|
||
"stepChooseBody": "Rescan the default location, point at any folder you've extracted history into, or upload files/archives directly.",
|
||
"stepVerify": "4. Verify tokens and cost",
|
||
"stepVerifyBody": "After import, open Analytics → Cost to confirm the breakdown. Re-importing the same session is always safe.",
|
||
"defaultLocation": "Default location on this machine",
|
||
"locationFound": "Folder found",
|
||
"locationMissing": "Folder not found",
|
||
"projectsLabel": "projects",
|
||
"jsonlLabel": "JSONL files",
|
||
"modeRescan": "Rescan default folder",
|
||
"modeRescanDesc": "Re-read ~/.claude/projects and import anything new.",
|
||
"modeFolder": "Scan a folder",
|
||
"modeFolderDesc": "Scan any directory on this machine for JSONL transcripts (walks subfolders).",
|
||
"modeUpload": "Upload files",
|
||
"modeUploadDesc": "Drop JSONL files or an archive (.zip / .tar.gz) directly into the browser.",
|
||
"modeBackup": "Restore backup",
|
||
"modeBackupDesc": "Import a dashboard export (.json) from Export data — merge another machine's history in.",
|
||
"backupHint": "Drop an export .json here or click to select",
|
||
"backupSub": "The file produced by the Export data button (top of Settings)",
|
||
"runRestore": "Restore",
|
||
"backupResult": {
|
||
"title": "Restore complete",
|
||
"sessionsImported": "Sessions added: {{count}}",
|
||
"sessionsSkipped": "Already present: {{count}}",
|
||
"events": "Events: {{count}}",
|
||
"pricing": "Pricing rules: {{count}}",
|
||
"detail": "{{agents}} agents · {{workflows}} workflows · {{runs}} runs · {{rules}} alert rules"
|
||
},
|
||
"folderPlaceholder": "/absolute/path/to/claude-history",
|
||
"folderHelper": "Absolute path. Tilde (~) is expanded. Subfolders are scanned recursively.",
|
||
"runRescan": "Rescan Now",
|
||
"runScan": "Scan Folder",
|
||
"runUpload": "Upload & Import",
|
||
"dropzoneHint": "Drag files here or click to select",
|
||
"dropzoneSub": "Accepts .jsonl, .meta.json, .zip, .tar, .tar.gz, .tgz, .gz",
|
||
"filesSelected": "{{count}} file(s) selected",
|
||
"clearSelection": "Clear",
|
||
"copy": "Copy",
|
||
"copied": "Copied",
|
||
"progress": {
|
||
"scan": "Scanning directory...",
|
||
"extract": "Extracting archives ({{processed}}/{{total}})...",
|
||
"parse": "Parsing transcripts ({{processed}}/{{total}})...",
|
||
"complete": "Import complete",
|
||
"error": "Import failed"
|
||
},
|
||
"result": {
|
||
"imported": "Imported: {{count}}",
|
||
"backfilled": "Enriched existing: {{count}}",
|
||
"skipped": "Already up to date: {{count}}",
|
||
"errors": "Errors: {{count}}",
|
||
"filesScanned": "Files scanned: {{count}}",
|
||
"title": "Last import result"
|
||
},
|
||
"errors": {
|
||
"noFiles": "No files selected",
|
||
"noJsonl": "No .jsonl files were found in the uploaded content",
|
||
"pathRequired": "Path is required",
|
||
"pathInvalid": "Path must be absolute",
|
||
"pathNotFound": "Path does not exist",
|
||
"pathNotDir": "Path is not a directory",
|
||
"generic": "Import failed: {{message}}"
|
||
}
|
||
},
|
||
"data": {
|
||
"title": "Data Management",
|
||
"description": "Database info, import/export, and cleanup.",
|
||
"dbOverview": "Database Overview",
|
||
"dbSize": "DB Size",
|
||
"loadingDb": "Loading database info...",
|
||
"sessionCleanup": "Session Cleanup",
|
||
"cleanupDesc": "Abandon stale sessions and purge old data",
|
||
"abandonAfter": "Abandon stale active sessions older than",
|
||
"purgeAfter": "Purge completed/errored sessions older than",
|
||
"confirmCleanup": "Confirm Cleanup",
|
||
"runCleanup": "Run Cleanup",
|
||
"nothingToClean": "Nothing to clean up",
|
||
"abandonedResult": " sessions abandoned",
|
||
"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",
|
||
"description": "Irreversible actions that delete data permanently",
|
||
"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",
|
||
"dialogTitle": "Clear all data?",
|
||
"exportFirst": "Export your data first.",
|
||
"typeToConfirm": "Type “{{phrase}}” to confirm:",
|
||
"phrase": "clear all data"
|
||
},
|
||
"autostart": {
|
||
"title": "Startup",
|
||
"label": "Start AgentHub automatically",
|
||
"desc_systemd": "Run the dashboard as a systemd --user service, so it starts at boot without Claude Code being opened. Turning it off keeps the running server up.",
|
||
"desc_launchd": "Run the dashboard as a LaunchAgent, so it starts at login without Claude Code being opened. Turning it off keeps the running server up.",
|
||
"unavailable": "Not available here: needs systemd --user on Linux, or a GUI login on macOS.",
|
||
"foreign": "A service named agenthub that AgentHub did not write already exists — AgentHub leaves it alone."
|
||
},
|
||
"tray": {
|
||
"label": "Show AgentHub icon in the status area",
|
||
"desc": "An AgentHub icon beside the clock (top bar, menu bar or notification area) to open the dashboard, quit it, and start it again after a quit.",
|
||
"unavailable": "Not available here: needs a graphical desktop session, and is off in server mode."
|
||
},
|
||
"quit": {
|
||
"label": "Quit AgentHub",
|
||
"desc": "Stop the dashboard so nothing runs in the background. Opening Claude Code no longer starts it; run `agenthub start` to bring it back.",
|
||
"button": "Quit",
|
||
"confirmTitle": "Quit AgentHub?",
|
||
"confirmMessage": "Every workspace terminal is closed — running agents stop — and the dashboard shuts down. It stays off until you run `agenthub start`.",
|
||
"confirmMessageAutostart": "Every workspace terminal is closed — running agents stop — and the dashboard shuts down. It stays off until you run `agenthub start`, or until the next boot/login (start automatically is on).",
|
||
"done": "AgentHub is stopping. Run `agenthub start` to start it again."
|
||
},
|
||
"about": {
|
||
"title": "System",
|
||
"release": "Release",
|
||
"uiBuild": "UI build v{{version}} (rebuild client to match)",
|
||
"uptime": "Uptime",
|
||
"nodejs": "Node.js",
|
||
"platform": "Platform",
|
||
"wsClients": "Live connections",
|
||
"wsClientsDesc": "Browser tabs and tools receiving live updates",
|
||
"loadingInfo": "Loading server info...",
|
||
"server": "Server",
|
||
"cpu": "CPU",
|
||
"cpuValue": "{{count}} cores · load {{load}}",
|
||
"memory": "Process memory",
|
||
"memoryValue": "{{rss}} RSS · heap {{used}} of {{limit}}",
|
||
"systemMemory": "System memory",
|
||
"systemMemoryValue": "{{used}} used of {{total}}",
|
||
"install": "Installation",
|
||
"installKind": {
|
||
"plugin": "Claude Code plugin",
|
||
"checkout": "Git checkout"
|
||
},
|
||
"latest": "Latest release",
|
||
"upToDate": "Up to date",
|
||
"updateAvailable": "Update available",
|
||
"unknown": "Unknown",
|
||
"database": "Database",
|
||
"dbFile": "Database file",
|
||
"journal": "Journal mode",
|
||
"activity": "Events recorded",
|
||
"activityValue": "{{m5}} in 5 min · {{m15}} in 15 min · {{h1}} in 1 h"
|
||
},
|
||
"tables": {
|
||
"sessions": "sessions",
|
||
"agents": "agents",
|
||
"events": "events",
|
||
"sessionsWithCost": "sessions with cost",
|
||
"pricingRules": "pricing rules"
|
||
},
|
||
"messages": {
|
||
"failedLoad": "Failed to load",
|
||
"failedSave": "Failed to save",
|
||
"failedDelete": "Failed to delete",
|
||
"unknownError": "Unknown",
|
||
"actionFailed": "Error: {{message}}"
|
||
},
|
||
"webhooks": {
|
||
"title": "Webhook Notifications",
|
||
"description": "Forward fired alerts to Slack, Discord, Microsoft Teams, or any HTTP endpoint. Delivery is automatic, retried on failure, and never blocks monitoring.",
|
||
"count_one": "{{count}} target",
|
||
"count_other": "{{count}} targets",
|
||
"add": "Add Webhook",
|
||
"loading": "Loading webhooks…",
|
||
"empty": "No webhooks configured. Add one to forward alerts to Slack, Discord, Teams, or a custom endpoint.",
|
||
"scopedTo_one": "{{count}} rule",
|
||
"scopedTo_other": "{{count}} rules",
|
||
"enabled": "Enabled",
|
||
"test": "Test",
|
||
"edit": "Edit",
|
||
"delete": "Delete",
|
||
"confirmDelete": "Confirm",
|
||
"testOk": "Delivered (HTTP {{status}})",
|
||
"testFail": "Failed: {{error}}",
|
||
"addTitle": "New Webhook",
|
||
"editTitle": "Edit Webhook",
|
||
"fieldName": "Name",
|
||
"fieldNamePlaceholder": "e.g. Team Slack #alerts",
|
||
"fieldType": "Type",
|
||
"type": {
|
||
"slack": "Slack",
|
||
"discord": "Discord",
|
||
"teams": "Microsoft Teams",
|
||
"generic": "Generic (custom JSON)"
|
||
},
|
||
"fieldUrl": "Webhook URL",
|
||
"urlKeepHint": "leave blank to keep current",
|
||
"urlKeepPlaceholder": "•••••••• (unchanged)",
|
||
"urlPlaceholder": {
|
||
"slack": "https://hooks.slack.com/services/…",
|
||
"discord": "https://discord.com/api/webhooks/…",
|
||
"teams": "https://outlook.office.com/webhook/…",
|
||
"generic": "https://example.com/webhook"
|
||
},
|
||
"fieldSecret": "Signing secret (optional)",
|
||
"secretPlaceholder": "HMAC-SHA256 secret",
|
||
"secretKeepPlaceholder": "•••••••• (leave blank to keep)",
|
||
"secretHint": "When set, requests are signed with an X-Webhook-Signature header.",
|
||
"fieldHeaders": "Custom headers (optional)",
|
||
"replaceHeaders": "Replace headers",
|
||
"headerKey": "Header",
|
||
"headerValue": "Value",
|
||
"addHeader": "Add header",
|
||
"scopeAll": "Receive alerts from all rules",
|
||
"enabledOnSave": "Enabled",
|
||
"save": "Save",
|
||
"create": "Create",
|
||
"cancel": "Cancel",
|
||
"urlOptional": "optional override",
|
||
"urlAuto": "URL is set automatically from the credentials below.",
|
||
"deleteTitle": "Delete webhook?",
|
||
"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.",
|
||
"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",
|
||
"description": "Define alert rules, route them to webhook channels, and review what has fired - all in one place.",
|
||
"tabRules": "Rules",
|
||
"tabChannels": "Channels",
|
||
"tabActivity": "Activity",
|
||
"rulesHint": "Conditions that trigger an alert. Evaluated server-side against the live event stream.",
|
||
"rulesEmptyHint": "Add a rule to start alerting on errors, inactivity, stuck agents, or token thresholds."
|
||
},
|
||
"jumpTo": "Jump to",
|
||
"webhookGuides": {
|
||
"slack": {
|
||
"steps": [
|
||
"Create or open a Slack app at api.slack.com/apps.",
|
||
"Turn on 'Incoming Webhooks', then click 'Add New Webhook to Workspace'.",
|
||
"Choose the channel to post to and authorize.",
|
||
"Copy the generated URL (https://hooks.slack.com/services/…) and paste it above."
|
||
]
|
||
},
|
||
"discord": {
|
||
"steps": [
|
||
"Open your server → Server Settings → Integrations → Webhooks.",
|
||
"Click 'New Webhook', pick a channel, optionally rename it.",
|
||
"Click 'Copy Webhook URL' and paste it above."
|
||
]
|
||
},
|
||
"teams": {
|
||
"steps": [
|
||
"In the target Teams channel, click ⋯ → 'Workflows'.",
|
||
"Pick the template 'Post to a channel when a webhook request is received'.",
|
||
"Finish the flow and copy the generated HTTP POST URL.",
|
||
"Paste it above. (Classic Office 365 connectors were retired in 2025 - use Workflows.)"
|
||
]
|
||
},
|
||
"google_chat": {
|
||
"steps": [
|
||
"Open the Google Chat space → space title → 'Apps & integrations'.",
|
||
"Click 'Webhooks' → 'Add webhook' and give it a name.",
|
||
"Copy the webhook URL and paste it above."
|
||
]
|
||
},
|
||
"mattermost": {
|
||
"steps": [
|
||
"Main Menu → Integrations → Incoming Webhooks (an admin must enable webhooks first).",
|
||
"Click 'Add Incoming Webhook' and choose a channel.",
|
||
"Save, then copy the webhook URL and paste it above."
|
||
]
|
||
},
|
||
"rocketchat": {
|
||
"steps": [
|
||
"Administration → Integrations → New → Incoming.",
|
||
"Enable it, pick a channel, and save.",
|
||
"Copy the 'Webhook URL' and paste it above."
|
||
]
|
||
},
|
||
"telegram": {
|
||
"steps": [
|
||
"Message @BotFather, run /newbot, and copy the bot token.",
|
||
"Add the bot to your group/channel (or just DM it).",
|
||
"Find the chat ID: send a message, open https://api.telegram.org/bot<token>/getUpdates, read result[].message.chat.id.",
|
||
"Enter the Bot token and Chat ID above - no URL needed."
|
||
]
|
||
},
|
||
"pagerduty": {
|
||
"steps": [
|
||
"Open the target Service → Integrations → 'Add integration'.",
|
||
"Choose 'Events API v2'.",
|
||
"Copy the Integration Key (the routing key).",
|
||
"Enter it as the Routing key above - the Events API URL is prefilled."
|
||
]
|
||
},
|
||
"opsgenie": {
|
||
"steps": [
|
||
"Settings → Integrations → add an 'API' integration.",
|
||
"Copy the generated API key.",
|
||
"Note your account region (US or EU).",
|
||
"Enter the API key and region above - the alerts URL is derived from the region."
|
||
]
|
||
},
|
||
"splunk_oncall": {
|
||
"steps": [
|
||
"Integrations → REST Endpoint, and enable it.",
|
||
"Copy the REST URL - it already contains your API key.",
|
||
"Replace the trailing '$routing_key' with one of your routing keys.",
|
||
"Paste the full URL above."
|
||
]
|
||
},
|
||
"zapier": {
|
||
"steps": [
|
||
"Create a Zap with the trigger 'Webhooks by Zapier' → 'Catch Hook'.",
|
||
"Copy the custom webhook URL it gives you.",
|
||
"Paste it above. The alert arrives as JSON: { event, alert }."
|
||
]
|
||
},
|
||
"make": {
|
||
"steps": [
|
||
"Add a 'Webhooks' → 'Custom webhook' module as the first step of a scenario.",
|
||
"Click 'Add', create the hook, and copy its URL.",
|
||
"Paste it above, then run once so Make learns the payload shape."
|
||
]
|
||
},
|
||
"n8n": {
|
||
"steps": [
|
||
"Add a 'Webhook' node to your workflow; set the method to POST.",
|
||
"Copy the Production URL.",
|
||
"Activate the workflow and paste the URL above (http is allowed for self-hosted)."
|
||
]
|
||
},
|
||
"pipedream": {
|
||
"steps": [
|
||
"Create a workflow with an 'HTTP / Webhook' trigger.",
|
||
"Copy the unique endpoint URL.",
|
||
"Paste it above; inspect deliveries in the Pipedream event inspector."
|
||
]
|
||
},
|
||
"generic": {
|
||
"steps": [
|
||
"Point this at any endpoint that accepts a JSON POST (https, or http for local testing).",
|
||
"Body shape: { event: 'alert.triggered', source, sent_at, alert: { … } }.",
|
||
"Optional: set a signing secret (HMAC-SHA256 over the body → X-Webhook-Signature header) and custom headers.",
|
||
"Tip: use a free inspector like webhook.site to see the exact payload."
|
||
]
|
||
}
|
||
},
|
||
"remoteSources": {
|
||
"title": "Remote Data Sources",
|
||
"description": "Collect Claude Code usage from other machines over SSH - e.g. a dev box or cloud VM you drive over SSH while running this dashboard locally. Authentication uses your own SSH setup (~/.ssh/config, keys, agent); no passwords are stored here.",
|
||
"scopeTitle": "Data scope",
|
||
"scopeDesc": "Choose which machines' data the whole dashboard shows. Changes apply immediately across every page — sessions, analytics, and cost.",
|
||
"scopeAll": "All sources",
|
||
"scopeAllDesc": "This machine plus every configured remote source, combined.",
|
||
"scopeLocal": "This machine only",
|
||
"scopeLocalDesc": "Only sessions collected locally — hides all remote-source data.",
|
||
"scopeSelected": "Selected sources",
|
||
"scopeSelectedDesc": "Pick exactly which machines to include, below.",
|
||
"scopeSelectedCount": "{{n}} of {{total}} selected",
|
||
"scopePickMachines": "Machines to include",
|
||
"thisMachine": "This machine",
|
||
"listTitle": "Configured sources",
|
||
"add": "Add source",
|
||
"addTitle": "Add a remote source",
|
||
"editTitle": "Edit source",
|
||
"fieldLabel": "Label",
|
||
"fieldHost": "SSH host",
|
||
"fieldPort": "Port (optional)",
|
||
"fieldIdentity": "Identity file (optional)",
|
||
"fieldRemoteHome": "Remote Claude home (optional)",
|
||
"fieldRemoteHomeHint": "Linux/macOS: default ~/.claude (or an absolute path like /home/you/.claude). Windows SSH + Claude in WSL: leave blank (auto-detect) or use wsl:~/.claude. Native Windows: C:/Users/you/.claude.",
|
||
"fieldEnabled": "Sync automatically in the background",
|
||
"empty": "No remote sources yet.",
|
||
"emptyHint": "Add a machine you reach over SSH to pull its Claude Code usage in.",
|
||
"paused": "Auto-sync off",
|
||
"sessionCount": "{{n}} sessions",
|
||
"sessionCountLinked": "{{n}} linked",
|
||
"sessionCountHint": "Sessions linked to this source (not every session visible when data scope is All)",
|
||
"lastSync": "Last sync: {{when}}",
|
||
"neverSynced": "Never synced",
|
||
"imported": "{{n}} imported",
|
||
"syncNew": "{{n}} new",
|
||
"syncOnRemote": "{{n}} on remote",
|
||
"test": "Test",
|
||
"syncNow": "Sync",
|
||
"syncAll": "Sync all",
|
||
"enable": "Enable",
|
||
"disable": "Disable",
|
||
"confirmDelete": "Remove this source?",
|
||
"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",
|
||
"fieldSyncCodex": "Also pull Codex sessions",
|
||
"fieldRemoteCodexHome": "Remote Codex home (optional)",
|
||
"fieldRemoteCodexHomeHint": "Default ~/.codex (wsl:~/.codex when the Claude home is in WSL). Its sessions/ folder is copied, and the sessions show up as Codex sessions of this source, with their tokens and cost.",
|
||
"codexOn": "+ Codex",
|
||
"syncCodex": "{{n}} Codex",
|
||
"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).",
|
||
"aiProxy": {
|
||
"title": "AI Proxy",
|
||
"description": "For example 9Router, OpenRouter or a self-hosted gateway. Save one here, then pick it for a session in the workspace prompt box.",
|
||
"add": "Add profile",
|
||
"edit": "Edit",
|
||
"remove": "Remove",
|
||
"empty": "No proxy profile saved yet. Native runs against the vendor's own API.",
|
||
"builtinHint": "Built in — this is the vendor's own API, and it cannot be edited or removed.",
|
||
"colLabel": "Profile",
|
||
"colBaseUrl": "Endpoint",
|
||
"colModel": "Model",
|
||
"colKey": "API key",
|
||
"keySet": "Saved",
|
||
"keyMissing": "None",
|
||
"fieldLabel": "Name",
|
||
"fieldLabelHint": "What you will see in the session's AI Proxy picker. Free text.",
|
||
"fieldBaseUrl": "Base URL",
|
||
"fieldBaseUrlHint": "The proxy's root URL, without /v1 — e.g. http://localhost:20128. Claude Code adds /v1/messages and Codex /v1/responses; a /v1 you type is dropped.",
|
||
"fieldApiKey": "API key",
|
||
"fieldApiKeyHint": "Stored on this machine at 0600 and never sent back to the browser.",
|
||
"fieldApiKeyKeep": "Leave blank to keep the saved key.",
|
||
"fieldModel": "Model",
|
||
"fieldModelHint": "Used for every tier unless you override one below. Many proxies accept one symbolic name.",
|
||
"fieldBehavesAs": "Behaves as (Claude Code)",
|
||
"fieldBehavesAsHint": "Optional. The Claude model id Claude Code should treat this proxy's model names as (effort defaults, context window), e.g. claude-opus-5-5. Fill it in when Claude Code says a model isn't described by its model catalog, and name the model the proxy really sends to. While set, it replaces your own modelPicker setting in these sessions.",
|
||
"perTier": "Per-tier overrides",
|
||
"perTierHint": "Leave a field blank to use the model above.",
|
||
"tier": {
|
||
"opus": "Opus",
|
||
"sonnet": "Sonnet",
|
||
"haiku": "Haiku",
|
||
"smallFast": "Small / fast",
|
||
"subagent": "Subagent"
|
||
},
|
||
"save": "Save",
|
||
"cancel": "Cancel",
|
||
"removeConfirm": "Remove the profile \"{{label}}\"? Its session files go with it, and a session that ran on it resumes on the vendor's own API.",
|
||
"loading": "Loading profiles…",
|
||
"test": "Test",
|
||
"testing": "Testing…",
|
||
"testOk": "answered — {{model}} is reachable with this key.",
|
||
"testFailed": "no answer ({{status}}): {{message}}"
|
||
},
|
||
"aiTools": {
|
||
"title": "AI Tools",
|
||
"description": "AI coding CLIs AgentHub can run in a workspace. Detected on this machine's PATH; a disabled tool is hidden from Add workspace.",
|
||
"installed": "Installed ({{count}} detected)",
|
||
"available": "Available to install ({{count}})",
|
||
"refresh": "Refresh",
|
||
"noneInstalled": "No AI tool found on PATH. Install one, then press Refresh.",
|
||
"default": "Default",
|
||
"setDefault": "Set default",
|
||
"enabled": "Enabled",
|
||
"disabled": "Disabled",
|
||
"enabledOf": "{{tool}} enabled",
|
||
"homepage": "Homepage",
|
||
"homepageOf": "{{tool}} homepage",
|
||
"install": "Install",
|
||
"update": "Update",
|
||
"updateAll": "Update all ({{count}})",
|
||
"runScript": "Download {{url}} and run it with bash",
|
||
"confirmInstall": "Install {{tool}}?",
|
||
"confirmUpdate": "Update {{tool}}?",
|
||
"confirmUpdateAll": "Update AI tools?",
|
||
"confirmBody": "AgentHub will run on this machine:",
|
||
"run": "Run",
|
||
"cancel": "Cancel",
|
||
"jobRunning": "Running…",
|
||
"jobOk": "Done",
|
||
"jobFailed": "Failed (exit {{code}})",
|
||
"showLog": "Show log",
|
||
"hideLog": "Hide log"
|
||
},
|
||
"appearance": {
|
||
"title": "Appearance",
|
||
"description": "Colour mode and theme. Saved in this browser only.",
|
||
"mode": "Mode",
|
||
"modes": {
|
||
"dark": "Dark",
|
||
"light": "Light",
|
||
"system": "System"
|
||
},
|
||
"darkThemes": "Dark themes",
|
||
"lightThemes": "Light themes",
|
||
"active": "· in use now",
|
||
"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.",
|
||
"theme": "Theme",
|
||
"pet": "Pet",
|
||
"petDescription": "The corner mascot: show it, its size, speech bubbles, and which pet it wears."
|
||
},
|
||
"gitCreds": {
|
||
"title": "Git credentials",
|
||
"description": "One login per host, shared by everyone using this AgentHub. A token is never shown again after it is saved.",
|
||
"add": "Add login",
|
||
"replace": "Replace token",
|
||
"remove": "Delete",
|
||
"removeConfirm": "Delete this git login? Dashboard fetch/pull/push to that host will ask for a login again.",
|
||
"save": "Save",
|
||
"cancel": "Cancel",
|
||
"fieldHost": "Server URL",
|
||
"fieldUser": "Username",
|
||
"fieldToken": "Password or access token",
|
||
"colHost": "Host",
|
||
"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",
|
||
"saved": "Login saved for {{host}}.",
|
||
"loading": "Loading…"
|
||
},
|
||
"homeDir": {
|
||
"save": "Save",
|
||
"saving": "Saving...",
|
||
"current": "Current:",
|
||
"saveFailed": "Failed to save the directory",
|
||
"envOwned": "This variable is set by the environment the dashboard started in, or by the checkout's .env — either wins at every start: a value saved here lasts until the next restart."
|
||
},
|
||
"codexHome": {
|
||
"title": "CODEX_HOME",
|
||
"description": "Root directory for Codex config and session journals. The dashboard reads it, writes AI Proxy layers into it, and starts every codex workspace with it.",
|
||
"restartNote": "A codex workspace already running keeps the home it started with, and shows as idle, until it is restarted.",
|
||
"placeholder": "/path/to/codex-home"
|
||
},
|
||
"codexHooks": {
|
||
"title": "Codex hooks",
|
||
"description": "Let Codex report to AgentHub as it works: each tool call in the session's timeline, \"Codex needs your permission\" on the workspace card and as a notification, and running/idle the moment a turn starts or ends. Tokens and cost come from Codex's journals either way.",
|
||
"notInstalled": "Not installed",
|
||
"untrusted": "Installed — waiting for your trust in Codex",
|
||
"trusted": "Installed and trusted",
|
||
"trustNote": "Codex runs a hook only after you trust it. The next time Codex starts it asks you to review new hooks: choose Trust all and continue (or run /hooks). Until then Codex skips them.",
|
||
"install": "Install",
|
||
"reinstall": "Reinstall",
|
||
"refresh": "Refresh",
|
||
"remove": "Remove",
|
||
"eventTrusted": "Trusted in Codex",
|
||
"eventUntrusted": "Not trusted in Codex yet",
|
||
"eventMissing": "Not installed",
|
||
"unsupported": "Codex hooks from AgentHub need a POSIX shell, so they are not available on Windows.",
|
||
"unreadable": "AgentHub cannot read {{path}}: {{error}}",
|
||
"failed": "Could not change Codex hooks: {{message}}"
|
||
},
|
||
"antigravityHooks": {
|
||
"title": "Antigravity hooks",
|
||
"description": "Let Antigravity's CLI (agy) report to AgentHub as it works: each tool call in the session's timeline, and running/idle the moment a run starts or ends. Tokens and cost come from agy's conversation files either way.",
|
||
"notInstalled": "Not installed",
|
||
"installed": "Installed",
|
||
"disabled": "Installed but switched off in hooks.json",
|
||
"note": "agy loads hooks at its next start and asks for no trust. The file is global, so the Antigravity IDE runs the hook too; AgentHub ignores what the IDE sends. agy has no hook for a permission prompt, so an Antigravity workspace cannot show \"needs your permission\".",
|
||
"install": "Install",
|
||
"reinstall": "Reinstall",
|
||
"refresh": "Refresh",
|
||
"remove": "Remove",
|
||
"eventInstalled": "Installed",
|
||
"eventMissing": "Not installed",
|
||
"unsupported": "Antigravity hooks from AgentHub need a POSIX shell, so they are not available on Windows.",
|
||
"unreadable": "AgentHub cannot read {{path}}: {{error}}",
|
||
"failed": "Could not change Antigravity hooks: {{message}}"
|
||
},
|
||
"toolTab": {
|
||
"update": "Update…",
|
||
"usage_one": "{{count}} session · ${{cost}}",
|
||
"usage_other": "{{count}} sessions · ${{cost}}",
|
||
"lanes": "Workspaces:",
|
||
"defaultModel": "Default model",
|
||
"defaultModelHint": "The model a new session on this tool starts on. The workspace prompt box can still pick another one.",
|
||
"saveDefaultModel": "Save default model",
|
||
"config": "Config files",
|
||
"configHint": "This tool's own settings files. A save is checked for valid syntax, the old text is backed up in AgentHub's data folder, and nothing is saved if the file changed since you opened it.",
|
||
"missing": "This file does not exist yet",
|
||
"save": "Save",
|
||
"close": "Close",
|
||
"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",
|
||
"back": "Back to Workspace",
|
||
"group": {
|
||
"general": "General",
|
||
"agents": "Agents",
|
||
"data": "Data"
|
||
},
|
||
"section": {
|
||
"appearance": {
|
||
"title": "Appearance",
|
||
"description": "Language, colour mode and theme, and the corner pet."
|
||
},
|
||
"notifications": {
|
||
"title": "Notifications",
|
||
"description": "Browser notifications, alert rules and webhooks."
|
||
},
|
||
"agents": {
|
||
"title": "AI tools",
|
||
"description": "The AI coding CLIs AgentHub can run: enable, set the default, install and update."
|
||
},
|
||
"claudeCode": {
|
||
"title": "Claude Code",
|
||
"description": "Claude Code's own configuration, and what AgentHub reads from it."
|
||
},
|
||
"codex": {
|
||
"title": "Codex",
|
||
"description": "Codex's own configuration, and what AgentHub reads from it."
|
||
},
|
||
"tool": {
|
||
"description": "{{tool}}: path, usage, default model and config files."
|
||
},
|
||
"aiProxy": {
|
||
"title": "AI Proxy",
|
||
"description": "Endpoints that stand in front of Claude Code and Codex."
|
||
},
|
||
"pricing": {
|
||
"title": "Pricing",
|
||
"description": "Model prices for every vendor, used to estimate cost. Rates per million tokens (USD); % is a wildcard in a pattern; a model's introductory rate is shown in violet."
|
||
},
|
||
"data": {
|
||
"title": "Database",
|
||
"description": "Total cost, database overview, import, remote sources, export, cleanup and the danger zone."
|
||
},
|
||
"reports": {
|
||
"title": "Snapshots & reports",
|
||
"description": "Read-only session snapshots behind their own links, and analytics summaries written on a schedule."
|
||
},
|
||
"system": {
|
||
"title": "System",
|
||
"description": "Version, install, start at login, server runtime and the database file."
|
||
},
|
||
"git": {
|
||
"title": "Git",
|
||
"description": "Logins AgentHub gives git for a dashboard fetch, pull or push, and which worktrees Add folder suggests."
|
||
}
|
||
},
|
||
"backPrevious": "Back",
|
||
"unknownSection": "There is no “{{section}}” settings page — showing Appearance instead."
|
||
},
|
||
"search": {
|
||
"placeholder": "Search settings",
|
||
"noMatch": "No setting matches “{{query}}”.",
|
||
"results": "Search results"
|
||
},
|
||
"worktrees": {
|
||
"title": "Worktree suggestions",
|
||
"description": "When you add a folder to a workspace, the repo's worktrees that have no workspace are suggested. Saved in this browser only.",
|
||
"showUntracked": "Show untracked worktrees",
|
||
"showUntrackedDesc": "Suggest a repository's worktrees that have no workspace yet.",
|
||
"claude": "Claude Code worktrees",
|
||
"claudeDesc": "Worktrees under <repo>/.claude/worktrees/, made by Claude Code's own agents.",
|
||
"agenthub": "AgentHub-managed worktrees",
|
||
"agenthubDesc": "Worktrees AgentHub created under its workspaces root."
|
||
},
|
||
"language": {
|
||
"title": "Language",
|
||
"description": "The language of the whole dashboard, remembered in this browser.",
|
||
"label": "Interface language",
|
||
"names": {
|
||
"en": "English",
|
||
"vi": "Tiếng Việt"
|
||
}
|
||
},
|
||
"terminalFont": {
|
||
"title": "Terminal font",
|
||
"description": "The font of the workspace terminals. Takes effect the next time a terminal opens. Saved in this browser only.",
|
||
"label": "Font",
|
||
"names": {
|
||
"jetbrains": "JetBrains Mono",
|
||
"maple": "Maple Mono (rounded)",
|
||
"system": "System font"
|
||
},
|
||
"systemNote": "Your browser's fixed-width font. It may lack some Vietnamese letters (ấ, ế, ố…), which then draw out of line.",
|
||
"preview": "Preview"
|
||
},
|
||
"rowMenu": {
|
||
"copyHost": "Copy host",
|
||
"copyUrl": "Copy endpoint",
|
||
"copyPattern": "Copy model pattern",
|
||
"copyPath": "Copy path",
|
||
"enable": "Enable",
|
||
"disable": "Disable"
|
||
},
|
||
"snapshots": {
|
||
"title": "Session snapshots",
|
||
"description": "Created from a session's page with Snapshot. They survive Clear Data; delete them here.",
|
||
"empty": "No snapshots yet.",
|
||
"events": "{{n}} events",
|
||
"redacted": "Paths redacted",
|
||
"open": "Open",
|
||
"copyLink": "Copy link",
|
||
"delete": "Delete",
|
||
"deleteTitle": "Delete this snapshot?",
|
||
"deleteBody": "Its link stops working. The session itself is not touched.",
|
||
"cancel": "Cancel"
|
||
},
|
||
"pushIngest": {
|
||
"title": "Push ingest",
|
||
"description": "For a machine this dashboard cannot reach over SSH: it pushes its own hooks to POST /api/hooks/ingest-batch with a token made here. Its sessions are tagged with the name it sends (push:<name>) and show live status and events; their token cost needs the transcripts, which only an SSH source brings.",
|
||
"on": "On — a token exists",
|
||
"off": "Off — no token yet",
|
||
"create": "Create token",
|
||
"rotate": "Rotate token",
|
||
"revoke": "Revoke",
|
||
"rotateConfirm": "Make a new token? The current one stops working at once.",
|
||
"revokeConfirm": "Revoke the token and turn push ingest off?",
|
||
"shownOnce": "Copy this token now: only its hash is stored, so it is never shown again.",
|
||
"copy": "Copy",
|
||
"envOwned": "AGENTHUB_PUSH_TOKEN_SHA256 is set by the environment the dashboard started in; change it there.",
|
||
"reachHint": "The other machine must reach this dashboard: start it with DASHBOARD_HOST (and DASHBOARD_ALLOWED_HOSTS for its name). Over plain http the token crosses the network readable — use it only on a network you trust, or behind TLS. The forwarder below keeps the token in a header file, never on a command line:",
|
||
"limits": "At most 500 events and 1 MB per request. A hook for a session another source owns is refused; transcript paths are dropped (they name files on the sender). Codex hooks are taken; Antigravity hooks are not."
|
||
},
|
||
"privacy": {
|
||
"title": "Privacy",
|
||
"description": "What AgentHub keeps from hooks and imported history. Both are off by default and apply to new data only.",
|
||
"redact": "Redact secrets before storing",
|
||
"redactHint": "API keys and tokens of known shapes, bearer headers, private keys and password=/TOKEN= values in event payloads and summaries become [redacted]. The transcripts on disk are the CLIs' own files and are not changed.",
|
||
"ignore": "Ignored folders",
|
||
"ignoreHint": "One absolute path per line. Hooks from these folders, and anything under them, are dropped whole; history import and the Codex reader skip their sessions. AGENTHUB_IGNORE_CWD sets the same list.",
|
||
"envOwned": "A value here is set by the environment the dashboard started in, and cannot be changed from this page."
|
||
},
|
||
"reports": {
|
||
"title": "Scheduled reports",
|
||
"description": "A summary of the last days — sessions, events, tokens, cost by model and by AI tool, top tools, budgets — written as HTML or JSON on a schedule. Reports and their history survive Clear Data.",
|
||
"add": "New report",
|
||
"defaultName": "Weekly summary",
|
||
"empty": "No scheduled report yet.",
|
||
"name": "Name",
|
||
"windowDays": "Days covered",
|
||
"frequency": "Frequency",
|
||
"daily": "Daily",
|
||
"weekly": "Weekly",
|
||
"weekday": "Day",
|
||
"hour": "Time",
|
||
"windowHint": "A report covers the full days before the day it runs, at this browser's time zone.",
|
||
"save": "Save",
|
||
"cancel": "Cancel",
|
||
"enabled": "Enabled",
|
||
"runNow": "Run now",
|
||
"history": "History",
|
||
"edit": "Edit",
|
||
"delete": "Delete",
|
||
"everyDay": "Every day at {{time}}",
|
||
"everyWeek": "Every {{day}} at {{time}}",
|
||
"window_one": "last {{count}} day",
|
||
"window_other": "last {{count}} days",
|
||
"lastRun": "Last run {{at}}",
|
||
"noRuns": "No runs yet.",
|
||
"trigger": {
|
||
"schedule": "Scheduled",
|
||
"manual": "Manual"
|
||
},
|
||
"download": "Download {{format}}",
|
||
"deleteTitle": "Delete this report?",
|
||
"deleteBody": "Its schedule, its run history and the files it wrote are deleted."
|
||
},
|
||
"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."
|
||
},
|
||
"pricingLink": {
|
||
"title": "Model pricing",
|
||
"description": "Prices for every vendor's models live on one page.",
|
||
"open": "Open Pricing"
|
||
}
|
||
}
|