Performance (measured with 5,900 messages: open 9 s -> 0.7 s, typing 440 ms -> 25 ms)
- GET /sessions/{id}?limit=N loads the end of a chat (from the last summary
on, at most N); /sessions/{id}/messages?before|after|around loads more
(scrolling up stops at a summary unless asked). Without parameters the
full history as before (terminal client).
- Chat view: memoised message list (typing, streaming and status changes no
longer re-render the history), finished turns fold into "N steps · M files"
with the answer visible, tool card bodies and summaries are built only when
opened, scroll-to-bottom only when content changes.
Search: /sessions/{id}/search over the whole chat; a hit loads its part
(around) and marks the message, "back to the latest messages" returns.
Media: /sessions/{id}/media lists images, videos and audio of a chat and its
subagents (generated images, tool output, files written, media in answers,
attachments); ⋯ -> Media shows them with filters, a large view and a jump to
the message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
994 lines
49 KiB
TypeScript
994 lines
49 KiB
TypeScript
// Reference language. Every other language must define the same keys.
|
||
export const en = {
|
||
"common.loading": "Loading…",
|
||
"common.save": "Save",
|
||
"common.add": "Add",
|
||
"common.edit": "Edit",
|
||
"common.delete": "Delete",
|
||
"common.remove": "Remove",
|
||
"common.close": "Close",
|
||
"common.collapse": "Collapse",
|
||
|
||
"nav.menu": "Menu",
|
||
"nav.settings": "Settings",
|
||
"nav.stats": "Statistics",
|
||
|
||
"nav.images": "Images",
|
||
"images.disabled": "Image generation is not set up: an admin enables it under Settings → General (fal.ai key in FAL_KEY).",
|
||
"images.promptPlaceholder": "Describe the image: subject, style, composition, colours, lighting… (Ctrl+Enter)",
|
||
"images.model": "Model",
|
||
"images.size": "Format",
|
||
"images.count": "Number",
|
||
"images.countN": "{n}×",
|
||
"images.folder": "Folder",
|
||
"images.generate": "Generate",
|
||
"images.generating": "Generating…",
|
||
"images.empty": "No images yet.",
|
||
"images.reuse": "Reuse prompt",
|
||
"images.copyPath": "Copy file path",
|
||
"images.deleteConfirm": "Delete this image (including the file)?",
|
||
"images.size.square_hd": "Square HD",
|
||
"images.size.square": "Square",
|
||
"images.size.landscape_4_3": "Landscape 4:3",
|
||
"images.size.landscape_16_9": "Landscape 16:9",
|
||
"images.size.portrait_4_3": "Portrait 3:4",
|
||
"images.size.portrait_16_9": "Portrait 9:16",
|
||
"settings.images": "Image generation (fal.ai)",
|
||
"settings.imagesEnabled": "Enabled",
|
||
"settings.imagesKey": "API key",
|
||
"settings.imagesDefault": "Default model",
|
||
"settings.imagesDir": "Folder in the project",
|
||
"settings.imagesHint": "Models and prices per image are edited in the config file ([images]).",
|
||
"budget.plan": "Go plan ({v}/month)",
|
||
"budget.window.5h": "5 hours",
|
||
"budget.window.week": "7 days",
|
||
"budget.window.month": "Month",
|
||
"settings.planLimit": "Plan limit (USD/month)",
|
||
"settings.planLimitHint": "opencode Go: the monthly usage limit of your plan. CodeCraft tracks the allowance each response reports (5 hours 20 %, week 50 %, month 100 %) – only usage through CodeCraft.",
|
||
"status.plan": "Go {pct} ({window})",
|
||
"budget.title": "Budgets this month",
|
||
"budget.spent": "Spent",
|
||
"budget.budget": "Budget",
|
||
"budget.remaining": "Remaining",
|
||
"budget.provider": "According to provider",
|
||
"budget.balance": "Balance {v}",
|
||
"budget.providerSpent": "Billed {v}",
|
||
"budget.orgWide": "Organisation-wide cost report of the provider",
|
||
"budget.remoteError": "not available",
|
||
"budget.hint": "Spent = costs recorded by CodeCraft with your configured prices. Provider values come from their APIs (OpenRouter, Anthropic with admin key, fal.ai with admin key).",
|
||
"budget.chip": "Budget {name}: {p}",
|
||
"budget.chipHint": "A monthly budget is nearly used up – see Statistics.",
|
||
"settings.monthlyBudget": "Monthly budget",
|
||
"settings.monthlyBudgetTotal": "Monthly budget (total)",
|
||
"settings.monthlyBudgetHint": "In the configured currency; 0 = none. Warnings appear in the chat header.",
|
||
"settings.budgetWarning": "Warn at",
|
||
"settings.adminKey": "Admin key (optional)",
|
||
"settings.adminKeyHint": "Anthropic Admin API key (sk-ant-admin01-…) to show the real, organisation-wide monthly cost.",
|
||
"settings.fetchPrices": "Fetch prices",
|
||
"settings.pricesFetched": "Prices updated for {n} models – save to keep them.",
|
||
"stats.perMillion": "per 1M tok",
|
||
"stats.perMillionHint": "Effective cost per million tokens (input incl. cache + output)",
|
||
"queue.pending": "{n} message(s) waiting – delivered at the agent's next step",
|
||
"queue.stopped": "{n} message(s) waiting",
|
||
"queue.sendNow": "Send now",
|
||
"queue.remove": "Remove from queue",
|
||
"queue.backgroundResult": "Result of a background task",
|
||
"permissionMode.auto": "Automatic (asks once, safe steps run)",
|
||
"nav.files": "Files",
|
||
"files.search": "Search files…",
|
||
"files.newFile": "New file",
|
||
"files.newFolder": "New folder",
|
||
"files.upload": "Upload",
|
||
"files.showHidden": "Show hidden files",
|
||
"files.newFileName": "File name:",
|
||
"files.newFolderName": "Folder name:",
|
||
"files.renameTo": "New name:",
|
||
"files.copyTo": "Name of the copy:",
|
||
"files.chatHere": "Open chat here",
|
||
"files.newTab": "Open file manager",
|
||
"files.closeTab": "Close file manager",
|
||
"files.rename": "Rename",
|
||
"files.duplicate": "Duplicate",
|
||
"files.download": "Download",
|
||
"files.actions": "Actions",
|
||
"files.deleteConfirm": "Delete \"{name}\"?",
|
||
"files.deleteFolderConfirm": "Delete the folder \"{name}\" with everything in it?",
|
||
"files.noHits": "No matches",
|
||
"files.emptyFolder": "Empty folder",
|
||
"files.dropHint": "Drop files here to upload",
|
||
"files.selectFile": "Select a file",
|
||
"files.edit": "Edit",
|
||
"files.preview": "Preview",
|
||
"files.binary": "Binary file – download it to open.",
|
||
"files.tooLarge": "File too large for the editor – download it.",
|
||
"files.discardChanges": "Discard unsaved changes?",
|
||
"files.conflict": "The file was changed on disk (e.g. by an agent) since you opened it. Overwrite it anyway?",
|
||
"files.tabFiles": "Files",
|
||
"git.init": "Initialise git repository",
|
||
"git.clone": "Clone repository",
|
||
"git.cloneUrl": "Repository URL (https://… or git@…):",
|
||
"git.cloneFolder": "Folder name:",
|
||
"git.branch": "Branch",
|
||
"git.newBranch": "New branch",
|
||
"git.newBranchName": "Name of the new branch:",
|
||
"git.fetch": "Fetch",
|
||
"git.pull": "Pull",
|
||
"git.push": "Push",
|
||
"git.done": "Done.",
|
||
"git.changes": "Changes",
|
||
"git.history": "History",
|
||
"git.staged": "Staged",
|
||
"git.unstaged": "Changes",
|
||
"git.stage": "Stage",
|
||
"git.unstage": "Unstage",
|
||
"git.stageAll": "Stage all",
|
||
"git.unstageAll": "Unstage all",
|
||
"git.discard": "Discard changes",
|
||
"git.discardConfirm": "Discard all changes to {file}?",
|
||
"git.openFile": "Open file",
|
||
"git.clean": "No changes.",
|
||
"git.message": "Commit message",
|
||
"git.amend": "Amend last commit",
|
||
"git.commit": "Commit",
|
||
"git.noCommits": "No commits yet.",
|
||
"git.noDiff": "No differences.",
|
||
"composer.folder": "folder",
|
||
"composer.attachedFiles": "Attached files (in the project, read them with your tools):",
|
||
"composer.uploading": "Uploading {n}…",
|
||
"usage.title": "Models and usage in this session",
|
||
"usage.period": "Period",
|
||
"usage.current": "current",
|
||
"usage.model": "Model",
|
||
"usage.prices": "Prices per 1M tokens",
|
||
"usage.usage": "Usage",
|
||
"usage.speed": "Speed",
|
||
"usage.cacheWrite": "Cache write",
|
||
"usage.contextNow": "Context now",
|
||
"usage.totalTime": "Total time",
|
||
"usage.inSession": "In this session",
|
||
"usage.providerMonth": "Provider this month",
|
||
"usage.byAgent": "By agent and model",
|
||
"preview.page": "Page {n} / {total}",
|
||
"preview.openBrowser": "Open in browser",
|
||
"preview.moreRows": "{n} more rows not shown",
|
||
"preview.moduleHint": "Tracker module – rendered to audio on the server (first playback may take a moment).",
|
||
"activity.phrases": "Pondering|Tinkering|Noodling|Brewing|Conjuring|Mulling|Crafting|Percolating|Ruminating|Whittling|Forging|Musing|Scheming|Untangling|Cogitating|Simmering|Wrangling|Hatching|Spelunking|Finagling|Concocting|Calibrating|Divining|Marinating",
|
||
"activity.prefill": "prefill",
|
||
"activity.generated": "generated",
|
||
"activity.prefilling": "reading prompt…",
|
||
"mcp.users": "Allowed users",
|
||
"mcp.usersPlaceholder": "admins only",
|
||
"mcp.usersHint": "Usernames separated by commas, or * for everybody. Admins always have access.",
|
||
"settings.budgetAction": "When a budget is used up",
|
||
"settings.budgetWarn": "Warn only",
|
||
"settings.budgetBlock": "Block new requests",
|
||
"settings.sandbox": "Shell sandbox",
|
||
"settings.sandboxAuto": "Users (not admins)",
|
||
"settings.sandboxAlways": "Everybody",
|
||
"settings.sandboxOff": "Off",
|
||
"settings.sandboxHint": "Shell commands and git run in a bubblewrap sandbox with only the user's folders writable.",
|
||
"users.quota": "Monthly quota",
|
||
"users.quotaHint": "Monthly cost limit (empty = unlimited)",
|
||
"users.quotaPrompt": "Monthly cost limit for {name} (empty = unlimited):",
|
||
"settings.tab.audit": "Audit",
|
||
"audit.title": "Audit log",
|
||
"audit.all": "All actions",
|
||
"audit.time": "Time",
|
||
"audit.action": "Action",
|
||
"audit.detail": "Details",
|
||
"audit.backup": "Backup",
|
||
"audit.backupHint": "ZIP with the configuration and a consistent copy of the database (sessions, users, statistics). Secrets referenced as ${VAR} are not included.",
|
||
"audit.download": "Download backup",
|
||
"craft.mode": "Craft mode",
|
||
"craft.modeHint": "Clean room: only what a user sees. Deep: also page sources and programs (Ghidra) – for re-creating, not copying.",
|
||
"craft.cleanRoom": "Clean room",
|
||
"craft.deep": "Deep",
|
||
"settings.tab.tools": "Tools",
|
||
"tools.installed": "installed",
|
||
"tools.install": "Install Ghidra",
|
||
"tools.reinstall": "Check / repair installation",
|
||
"tools.installing": "Installing (download ~800 MB, on ARM the decompiler is compiled – this takes several minutes)…",
|
||
"tools.ghidraHint": "Ghidra lets agents in craft Deep mode decompile programs (Windows .exe/.dll, Linux, DOS, …) to study how they work. Installed into the data volume together with its own JDK.",
|
||
"rewind.intro": "The conversation is reset to before this message; you can edit and resend it.",
|
||
"rewind.noFiles": "The agent did not change files since then.",
|
||
"rewind.restore": "Also restore the {n} file(s) the agent changed",
|
||
"rewind.willDelete": "will be deleted (new)",
|
||
"rewind.bashNote": "Changes made by shell commands (e.g. installed packages) are not restored.",
|
||
"rewind.confirm": "Rewind",
|
||
"files.discard": "Discard",
|
||
"files.overwrite": "Overwrite",
|
||
"shells.title": "Background shells",
|
||
"shells.chip": "{n}/{total} shells",
|
||
"shells.running": "running",
|
||
"shells.exited": "exited ({code})",
|
||
"shells.stop": "Stop",
|
||
"shells.noOutput": "(no output yet)",
|
||
"login.prompt": "Sign in to continue.",
|
||
"login.invalid": "Invalid token.",
|
||
"login.submit": "Sign in",
|
||
|
||
"sidebar.newSession": "New session",
|
||
"sidebar.noSessions": "No sessions yet",
|
||
"sidebar.today": "Today",
|
||
"sidebar.yesterday": "Yesterday",
|
||
"sidebar.week": "Last 7 days",
|
||
"sidebar.older": "Older",
|
||
"status.title": "Status",
|
||
"status.budgets": "Budgets",
|
||
"status.server": "Server",
|
||
"status.models": "Models",
|
||
"status.mcp": "MCP",
|
||
"status.level.ok": "all fine",
|
||
"status.level.warn": "partly unavailable",
|
||
"status.level.err": "unavailable",
|
||
"status.level.off": "none configured",
|
||
"status.providerOk": "{n} models · {ms} ms",
|
||
"status.notChecked": "not checked yet",
|
||
"status.recheck": "Check again",
|
||
"status.noProviders": "No providers enabled.",
|
||
"status.noMcp": "No MCP servers configured.",
|
||
"status.providerSettings": "Providers",
|
||
"status.mcpSettings": "MCP servers",
|
||
"sidebar.connected": "Connected",
|
||
"sidebar.disconnected": "Disconnected – reconnecting…",
|
||
"sidebar.needsInput": "Waiting for your input",
|
||
|
||
"session.untitled": "New session",
|
||
|
||
"wizard.title": "What do you want to do?",
|
||
"wizard.subtitle": "Pick a task, say what you want, then press Start.",
|
||
"wizard.whatToDo": "What do you want to do?",
|
||
"wizard.task.chat": "Just chat",
|
||
"wizard.task.chatDesc": "Ask, discuss, look things up – no project, no files",
|
||
"wizard.placeholder.chat": "What would you like to talk about?",
|
||
"wizard.task.craft": "Craft something",
|
||
"wizard.task.craftDesc": "Recreate a website, app, game or old program – or build something new",
|
||
"wizard.task.build": "Work on code",
|
||
"wizard.task.buildDesc": "Implement, fix and run things in a project",
|
||
"wizard.task.plan": "Plan",
|
||
"wizard.task.planDesc": "Read-only: analyse and propose a plan",
|
||
"wizard.whatToRecreate": "What do you want to recreate?",
|
||
"wizard.target.website": "A website",
|
||
"wizard.target.app": "An app",
|
||
"wizard.target.game": "A game",
|
||
"wizard.target.software": "Old software",
|
||
"wizard.target.fresh": "Nothing – start fresh",
|
||
"wizard.cleanDesc": "Only from what you can see: screenshots, visible text, behaviour",
|
||
"wizard.deepDesc": "Also study sources and binaries (Ghidra) – re-create, never copy",
|
||
"wizard.softwareNeedsDeep": "Analysing a program needs Deep mode (decompiling). In clean room mode only screenshots and your description are used.",
|
||
"wizard.sayWhat": "Say what you want",
|
||
"wizard.placeholder.website": "Anything special? e.g. only the start page, in React, dark theme …",
|
||
"wizard.placeholder.app": "Describe the app, attach screenshots …",
|
||
"wizard.placeholder.game": "Describe the game, attach screenshots or a video description …",
|
||
"wizard.placeholder.software": "What is the program? What should the new version run on? Attach the program, an archive or installer.",
|
||
"wizard.placeholder.fresh": "For example: a website for my bakery",
|
||
"wizard.placeholder.task": "What should be done?",
|
||
"wizard.enterHint": "Enter to start · Shift+Enter for a new line · drop or paste files",
|
||
"wizard.softwareHint": "Attach the program with its libraries, a zip/tar.gz or an installer – it goes to original/",
|
||
"wizard.attach": "Attach files",
|
||
"wizard.ideas": "Ideas:",
|
||
"wizard.idea.siteLanding": "Only the start page, as plain HTML/CSS",
|
||
"wizard.idea.siteShop": "All pages, in React with Tailwind",
|
||
"wizard.idea.appTodo": "A to-do app like in my screenshots",
|
||
"wizard.idea.appNotes": "A notes app with the same layout",
|
||
"wizard.idea.gameSnake": "A simple snake game in the browser",
|
||
"wizard.idea.gameBreakout": "A breakout clone with original graphics",
|
||
"wizard.idea.swDos": "An old DOS game – the new version should run in the browser",
|
||
"wizard.idea.swTool": "An old Windows tool – rebuild it as a cross-platform app",
|
||
"wizard.idea.freshBakery": "A website for my bakery",
|
||
"wizard.idea.freshSnake": "A simple snake game",
|
||
"wizard.idea.planFeature": "Plan a new feature for this project",
|
||
"wizard.idea.planRefactor": "Find the biggest weaknesses and propose a refactoring",
|
||
"wizard.idea.buildTests": "Add tests for the core module and fix what fails",
|
||
"wizard.idea.buildBug": "Find and fix the bug: ",
|
||
"wizard.builtBy": "Built by",
|
||
"wizard.newFolderIn": "Saved in a new folder in",
|
||
"wizard.existingFolder": "Works in",
|
||
"wizard.chooseFolder": "Choose a folder…",
|
||
"wizard.useNewFolder": "Use a new folder",
|
||
"wizard.start": "Start",
|
||
"wizard.creatingFolder": "Creating folder…",
|
||
"wizard.uploading": "Uploading files…",
|
||
"wizard.starting": "Starting…",
|
||
"phase.study": "Study",
|
||
"phase.specify": "Specify",
|
||
"phase.build": "Build",
|
||
"phase.check": "Check",
|
||
"phase.ready": "Ready",
|
||
"wizard.cloning": "Cloning repository…",
|
||
"wizard.originalTitle": "Upload the original software",
|
||
"wizard.originalHint": "Program folder as zip, tar.gz, 7z, an installer or single files – up to 500 MB each. Click or drop here.",
|
||
"wizard.whereLabel": "Where should it be built?",
|
||
"wizard.whereNew": "New folder",
|
||
"wizard.whereExisting": "Existing folder",
|
||
"wizard.whereGit": "Git repository",
|
||
"wizard.cloneInto": "Cloned into",
|
||
"rename.title": "Rename session",
|
||
"rename.generateWith": "Suggest a name with",
|
||
"rename.generate": "Generate",
|
||
"nav.terminal": "Terminal",
|
||
"terminal.new": "New terminal",
|
||
"terminal.chatTab": "Chat",
|
||
"terminal.tab": "Terminal {n}",
|
||
"terminal.closeConfirm": "Close {name}? The shell and everything running in it are stopped.",
|
||
"terminal.close": "Close terminal",
|
||
"terminal.here": "Open a terminal in this folder",
|
||
"terminal.connecting": "Connecting…",
|
||
"terminal.reconnecting": "Connection lost – reconnecting…",
|
||
"terminal.keys": "Extra keys",
|
||
"gitcred.title": "Git",
|
||
"gitcred.hint": "Used by your agents, the terminal and the git client to pull and push (e.g. Gitea/GitHub/GitLab access tokens). Stored in your home folder as git credential store – only your sessions can use them.",
|
||
"gitcred.name": "Commit name",
|
||
"gitcred.email": "Commit email",
|
||
"gitcred.credentials": "Credentials",
|
||
"gitcred.none": "No credentials yet.",
|
||
"gitcred.host": "Host",
|
||
"gitcred.user": "Username",
|
||
"gitcred.token": "Password or token",
|
||
"gitcred.add": "Add host",
|
||
"gitcred.saved": "Git settings saved",
|
||
"wizard.task.cad": "3D model for printing",
|
||
"wizard.task.cadDesc": "From a description or a hand-drawn sketch – OpenSCAD, STL/3MF",
|
||
"wizard.placeholder.cad": "Describe the part and its dimensions – or attach a photo of your sketch (with measurements).",
|
||
"wizard.idea.cadBox": "A box with a snap-on lid, inner size 80 × 50 × 30 mm",
|
||
"wizard.idea.cadBracket": "A wall bracket for a 25 mm pipe with two M4 screw holes",
|
||
"activity.reviewing": "Reviewing the result (round {round})…",
|
||
"chat.reviewPassed": "Review passed:",
|
||
"chat.todoReminder": "Back to work – {n} open todos:",
|
||
"agents.refineAfterTodos": "Review every completed todo and work until the list is done",
|
||
"agents.refineAfterTodosHint": "Each todo the agent marks completed is reviewed; with findings it is reopened. Ending the turn with open todos sends the agent back to work (for unattended runs, e.g. overnight). Off: only one review at the end of the turn.",
|
||
"chat.workSteps": "{n} steps",
|
||
"chat.workFiles": "{n} files",
|
||
"chat.loadOlder": "Load older messages",
|
||
"chat.showBeforeSummary": "Show the history before the summary",
|
||
"chat.backToLatest": "Back to the latest messages",
|
||
"chat.search": "Search in this chat",
|
||
"chat.searchPlaceholder": "Search messages, tool output …",
|
||
"chat.searchNone": "No matches",
|
||
"chat.searchHits": "{n} matches",
|
||
"chat.you": "You",
|
||
"chat.agent": "Agent",
|
||
"media.title": "Media",
|
||
"media.none": "No images, videos or audio in this chat yet.",
|
||
"media.filter.all": "All",
|
||
"media.filter.image": "Images",
|
||
"media.filter.video": "Videos",
|
||
"media.filter.audio": "Audio",
|
||
"media.source.generated": "generated",
|
||
"media.source.tool": "tool output",
|
||
"media.source.written": "written by the agent",
|
||
"media.source.answer": "in an answer",
|
||
"media.source.upload": "your attachment",
|
||
"media.showInChat": "Show in chat",
|
||
"media.open": "Open",
|
||
"media.prev": "Previous",
|
||
"media.next": "Next",
|
||
"media.back": "Back to the overview",
|
||
"chat.reviewRound": "Review {round}: changes requested",
|
||
"agents.refine": "Review loop",
|
||
"agents.refineRounds": "Review rounds per task",
|
||
"agents.refineOff": "0 = off",
|
||
"agents.refineModel": "Reviewer model",
|
||
"agents.refineCriteria": "Review criteria",
|
||
"agents.refineCriteriaHint": "Empty = default criteria of this mode. After each finished task a reviewer checks the result against your request; with findings the agent continues, up to the number of rounds.",
|
||
"agents.refineShort": "Review ×{n}",
|
||
"agents.deleteFile": "Delete agent file {path}?",
|
||
"nav.jobs": "Automations",
|
||
"jobs.intro": "Agents that start on a schedule. Each automation has its instructions in a Markdown file; name, schedule and settings are set here. Create one with “New automation” and work out the instructions with the assistant – or ask an agent in any chat (tool “schedule”). Every run appears as a normal chat.",
|
||
"jobs.none": "No automations yet.",
|
||
"jobs.schedule": "Schedule",
|
||
"jobs.next": "Next run",
|
||
"jobs.last": "Last run",
|
||
"jobs.mode": "Runs as",
|
||
"jobs.on": "On",
|
||
"jobs.off": "Off",
|
||
"jobs.enable": "Enable",
|
||
"jobs.disable": "Disable",
|
||
"jobs.runNow": "Run now",
|
||
"jobs.remove": "Remove",
|
||
"jobs.deleteConfirm": "Remove the automation “{name}”? The job file stays.",
|
||
"jobs.openRun": "Open run",
|
||
"jobs.prompt": "Instructions",
|
||
"jobs.register": "Register an existing file",
|
||
"jobs.registerHint": "Path to a Markdown file with instructions (older files with a schedule in the frontmatter are taken over):",
|
||
"jobs.registerBtn": "Register",
|
||
"jobs.status.running": "running",
|
||
"jobs.status.done": "done",
|
||
"jobs.status.timeout": "timed out",
|
||
"jobs.status.error": "error",
|
||
"chat.more": "More",
|
||
"worktree.title": "Isolated git worktree",
|
||
"worktree.hint": "The agent works on its own branch; your working copy on “{base}” stays untouched until you merge.",
|
||
"worktree.dirty": "{n} uncommitted files",
|
||
"worktree.commits": "{n} commits",
|
||
"worktree.merge": "Merge into {base}",
|
||
"worktree.remove": "Discard",
|
||
"worktree.mergeConfirm": "Commit open changes and merge {branch} into {base}?",
|
||
"worktree.removeConfirm": "Discard the worktree and branch {branch}? Unmerged changes are lost.",
|
||
"worktree.merged": "Merged into {base}",
|
||
"worktree.removed": "Worktree discarded",
|
||
"worktree.created": "The session now works in its own worktree",
|
||
"worktree.create": "Isolated worktree",
|
||
"worktree.busy": "Wait until the agent is done.",
|
||
"worktree.isolate": "Work in an isolated git worktree",
|
||
"worktree.isolateHint": "own branch, merge when done",
|
||
"worktree.creating": "Creating worktree…",
|
||
"files.up": "One folder up",
|
||
"permission.hunksHint": "{n} changes – untick the ones you don't want.",
|
||
"permission.applySelected": "Apply selected ({k}/{n})",
|
||
"effort.title": "Thinking effort for this message",
|
||
"effort.auto": "Effort: model default",
|
||
"effort.autoShort": "Effort: auto",
|
||
"effort.low": "Effort: low",
|
||
"effort.medium": "Effort: medium",
|
||
"effort.high": "Effort: high",
|
||
"effort.max": "Effort: max",
|
||
"regen.button": "Regenerate",
|
||
"regen.title": "Redo this answer",
|
||
"regen.hint": "Removes this answer (and restores files it changed), then runs your last message again – with the model and effort chosen here.",
|
||
"regen.go": "Regenerate",
|
||
"voice.start": "Dictate (speech recognition of your browser)",
|
||
"voice.stop": "Stop dictation",
|
||
"voice.denied": "Microphone access was denied – allow it in the browser settings.",
|
||
"voice.error": "Speech recognition failed",
|
||
"tokens.title": "API tokens",
|
||
"tokens.hint": "For the command line client (codecraft) and scripts: send as “Authorization: Bearer <token>”. Read-only tokens can only read (no prompts, no changes).",
|
||
"tokens.copyNow": "Copy the token now – it is shown only once:",
|
||
"telegram.title": "Telegram",
|
||
"telegram.intro": "Use CodeCraft from Telegram with your own bot: messages go to your current session, commands switch sessions, modes and models, approvals and questions come with buttons. Only your Telegram account can use the bot.",
|
||
"telegram.step1": "In Telegram, open @BotFather, send /newbot and follow the steps.",
|
||
"telegram.step2": "Paste the token BotFather gives you here.",
|
||
"telegram.connect": "Connect",
|
||
"telegram.checking": "Checking…",
|
||
"telegram.running": "running",
|
||
"telegram.stopped": "not running",
|
||
"telegram.paired": "paired",
|
||
"telegram.pairHint": "Last step: open your bot and send the code (or tap the link) – from then on only your Telegram account is served:",
|
||
"telegram.commands": "In Telegram: /help lists the commands – /sessions, /new, /mode, /model, /stop, /status, /costs …",
|
||
"telegram.disconnect": "Disconnect",
|
||
"telegram.disconnectConfirm": "Disconnect the Telegram bot? It stops answering; you can connect it again with its token.",
|
||
"tokens.copy": "Copy",
|
||
"tokens.copied": "Copied",
|
||
"tokens.name": "Name",
|
||
"tokens.scope": "Rights",
|
||
"tokens.lastUsed": "Last used",
|
||
"tokens.expires": "Expires",
|
||
"tokens.never": "never",
|
||
"tokens.revoke": "Revoke",
|
||
"tokens.revokeConfirm": "Revoke the token “{name}”? Programs using it lose access immediately.",
|
||
"tokens.namePlaceholder": "Name, e.g. laptop CLI",
|
||
"tokens.scopeFull": "Full access",
|
||
"tokens.scopeRead": "Read only",
|
||
"tokens.noExpiry": "No expiry",
|
||
"tokens.days": "days",
|
||
"tokens.create": "Create token",
|
||
"cli.title": "Terminal client",
|
||
"cli.intro": "Work with CodeCraft in your terminal like with Claude Code: the agent edits files and runs commands on your machine, while models, modes and rules come from this server (costs show up in your statistics). It can also run without a server using your own API keys.",
|
||
"cli.step1": "Install (Linux, x86_64 and arm64):",
|
||
"cli.step1Source": "Install from source (needs Rust; this server has no prebuilt binaries):",
|
||
"cli.step2": "Sign in with your CodeCraft account:",
|
||
"cli.step3": "Start it in a project folder with `codecraft`. Inside: /help, /model, /mode, Shift+Tab switches the mode, @ adds files. `codecraft update` updates it.",
|
||
"cli.downloads": "Direct downloads:",
|
||
"memory.title": "Personal memory",
|
||
"memory.hint": "What every agent should know about you – in all projects, in the web and in the terminal client (language, code style, tools you prefer …). Project facts are kept per project in .codecraft/memory.md.",
|
||
"memory.placeholder": "e.g. Answer in German. I prefer TypeScript and Rust. Never commit without asking.",
|
||
"memory.remembered": "Remembered",
|
||
"whatsnew.title": "What's new in {version}",
|
||
"update.available": "Update {version} available",
|
||
"settings.version": "Version",
|
||
"settings.fallback": "Fallback",
|
||
"settings.fallbackHint": "Used automatically when this model's host is unreachable or its provider budget is used up",
|
||
"install.label": "App",
|
||
"install.installed": "Installed",
|
||
"install.button": "Install CodeCraft as an app",
|
||
"install.hint.chrome": "Chrome on Android: menu ⋮ → “Install app” (or “Add to home screen” → Install). If only a shortcut appears, the server must be reachable from the internet for Google to build the app.",
|
||
"install.hint.samsung": "Samsung Internet: menu → “Add page to” → “Home screen”.",
|
||
"install.hint.firefox": "Firefox can't install web apps – open CodeCraft in Chrome (Android) or use “Add to home screen”.",
|
||
"install.hint.ios": "Safari: Share button → “Add to Home Screen”. Push notifications work only in the installed app.",
|
||
"install.hint.desktop": "Chrome/Edge: install icon in the address bar or menu → “Install CodeCraft”.",
|
||
"settings.pushTestFailed": "The push service rejected the notification",
|
||
"jobs.webhook": "Webhook",
|
||
"jobs.webhookOn": "Enable webhook",
|
||
"jobs.webhookOff": "Disable webhook",
|
||
"jobs.webhookRenew": "New secret",
|
||
"jobs.webhookShown": "Copy the secret now – it is shown only once:",
|
||
"jobs.webhookHelp": "POST any JSON to the URL; it is appended to the instructions. Authenticate with the header X-CodeCraft-Secret (or ?secret=…), or enter the secret as webhook secret in Gitea/GitHub (signature X-Gitea-Signature / X-Hub-Signature-256).",
|
||
"shareIn.title": "Shared with CodeCraft",
|
||
"shareIn.newChat": "Start a new chat",
|
||
"shareIn.appendTo": "or add to a recent session",
|
||
"common.back": "Back",
|
||
"settings.tab.modes": "My modes",
|
||
"modes.intro": "Your own modes: a prompt, a kind (coding or conversation), tools and an optional model. They appear in New session and in the mode selector of your chats – only for you.",
|
||
"modes.none": "You have no modes of your own yet.",
|
||
"modes.exists": "A mode named {name} already exists.",
|
||
"modes.promptPlaceholder": "e.g. You are a patient German teacher. Correct my sentences and explain briefly why.",
|
||
"agents.styleChatShort": "conversation",
|
||
"agents.styleCodingShort": "coding",
|
||
"settings.tab.templates": "Templates",
|
||
"templates.title": "Prompt templates",
|
||
"templates.filter": "Search templates…",
|
||
"templates.none": "No templates yet.",
|
||
"templates.global": "everyone",
|
||
"templates.manage": "Manage templates",
|
||
"templates.insert": "Insert",
|
||
"templates.personalTitle": "My templates",
|
||
"templates.personalHint": "Reusable prompts. Placeholders like {{file}} or {{goal: what should change}} are asked for when you insert the template.",
|
||
"templates.globalTitle": "Templates for everyone",
|
||
"templates.globalHint": "Every user sees these templates.",
|
||
"templates.name": "Name",
|
||
"templates.textPlaceholder": "Review {{file}} for bugs and suggest fixes.",
|
||
"templates.add": "Add template",
|
||
"templates.deleteConfirm": "Delete the template \"{name}\"?",
|
||
"palette.title": "Command palette",
|
||
"palette.placeholder": "Go to a session, page or action…",
|
||
"palette.newSession": "New session",
|
||
"palette.toggleTheme": "Switch light/dark mode",
|
||
"palette.nothing": "Nothing found.",
|
||
"palette.move": "move",
|
||
"palette.open": "open",
|
||
"palette.prevNext": "previous/next session",
|
||
"palette.close": "close",
|
||
"sidebar.pinned": "Pinned",
|
||
"sidebar.archive": "Archive",
|
||
"sidebar.byTime": "By date",
|
||
"sidebar.byProject": "By project",
|
||
"sidebar.groupByHint": "Group sessions by date or by project folder",
|
||
"sidebar.organise": "Organise session",
|
||
"sidebar.pin": "Pin to top",
|
||
"sidebar.unpin": "Unpin",
|
||
"sidebar.openBeside": "Open beside",
|
||
"chat.closePane": "Close this column",
|
||
"sidebar.groupMenu": "Folder options",
|
||
"sidebar.groupPin": "Pin to the top",
|
||
"sidebar.groupUnpin": "Unpin",
|
||
"sidebar.groupUp": "Move up",
|
||
"sidebar.groupDown": "Move down",
|
||
"sidebar.moveTo": "Move to folder…",
|
||
"sidebar.removeFromFolder": "Remove from folder",
|
||
"sidebar.archiveOne": "Archive",
|
||
"sidebar.unarchive": "Restore from archive",
|
||
"sidebar.moveTitle": "Move to folder",
|
||
"sidebar.moveHint": "Folders group sessions in the list. Type a new name.",
|
||
"sidebar.moveHintExisting": "Existing folders: {folders}. Type one of them or a new name.",
|
||
"sidebar.folderName": "Folder name",
|
||
"sidebar.move": "Move",
|
||
"backup.restore": "Restore",
|
||
"backup.restoreFile": "Restore from file…",
|
||
"backup.restoring": "Restoring…",
|
||
"backup.restoreTitle": "Restore backup?",
|
||
"backup.restoreConfirm": "Replace the database and the configuration with {file}? All sessions, users, statistics and settings are replaced by the state in the backup; files in the workspace stay as they are. The current state is backed up first. CodeCraft restarts – running agents are stopped.",
|
||
"backup.restarting": "Backup accepted – CodeCraft is restarting…",
|
||
"backup.notBack": "The server did not come back. It needs a restart policy (Docker: restart: unless-stopped) – start it again by hand.",
|
||
"backup.now": "Back up now",
|
||
"backup.running": "Backing up…",
|
||
"backup.created": "Backup {file} created.",
|
||
"backup.s3Failed": "Backup created, but the S3 upload failed",
|
||
"backup.daily": "Automatic daily backup",
|
||
"backup.at": "at",
|
||
"backup.oclock": "o'clock",
|
||
"backup.keep": "keep",
|
||
"backup.s3": "Copy to an S3 bucket (optional)",
|
||
"backup.s3Hint": "Any S3-compatible storage works (AWS, MinIO, Garage, Backblaze B2, Hetzner …). Keys may be ${ENV} references. The backup contains the config with API keys – use a private bucket.",
|
||
"backup.endpoint": "Endpoint",
|
||
"backup.region": "Region",
|
||
"backup.bucket": "Bucket",
|
||
"backup.prefix": "Prefix",
|
||
"backup.accessKey": "Access key",
|
||
"backup.secretKey": "Secret key",
|
||
"backup.secretStored": "stored – leave empty to keep",
|
||
"backup.s3Keep": "Keep in bucket (0 = all)",
|
||
"backup.last": "Last backup",
|
||
"backup.s3Ok": "uploaded",
|
||
"jobs.tplName": "Name",
|
||
"jobs.tplProject": "Project folder",
|
||
"jobs.tplMode": "Mode",
|
||
"new.title": "New session",
|
||
"new.directory": "Project directory",
|
||
"new.invalidFolderName": "Folder names cannot contain “/”.",
|
||
"new.up": "Up",
|
||
"new.noSubdirs": "No subdirectories",
|
||
"new.model": "Model",
|
||
"new.mode": "Mode",
|
||
"new.firstPrompt": "What should be done? (optional)",
|
||
"new.start": "Start in {dir}",
|
||
|
||
"activity.thinking": "Thinking…",
|
||
"activity.writing": "Writing…",
|
||
"activity.tool": "Running {tool}…",
|
||
"activity.subagent": "Subagent working: {name}",
|
||
"activity.waitingForYou": "Paused – waiting for your answer",
|
||
"activity.working": "Working",
|
||
"activity.titleBusy": "{n} working",
|
||
"activity.titleInput": "Input needed",
|
||
"chat.reasoningLive": "Thinking…",
|
||
"chat.reasoningDone": "Thought · {n} words",
|
||
"settings.reasoningDisplay": "Model reasoning",
|
||
"settings.reasoningCollapsed": "Collapsed (click to open)",
|
||
"settings.reasoningExpanded": "Always expanded",
|
||
"settings.reasoningHidden": "Off",
|
||
"settings.reasoningHint": "Thinking of the model (if the model and provider return it).",
|
||
"settings.reasoningLive": "Open while thinking, then collapse",
|
||
"chat.jumpLatest": "Jump to the latest message",
|
||
"sidebar.search": "Search chats…",
|
||
"sidebar.searchResults": "Results ({n})",
|
||
"sidebar.noResults": "Nothing found",
|
||
"chat.fork": "Fork: continue in a copy of this chat",
|
||
"chat.forked": "Forked – you are now in the copy",
|
||
"chat.export": "Export",
|
||
"chat.exportMd": "Markdown (.md)",
|
||
"chat.exportJson": "JSON (.json)",
|
||
"chat.empty": "Send a message to start.",
|
||
"chat.compactedAuto": "Context nearly full ({tokens} tokens) – conversation compacted automatically · summary",
|
||
"chat.compactedManual": "Conversation compacted at {tokens} tokens · summary",
|
||
"chat.compactingAuto": "Context nearly full – compacting the conversation automatically",
|
||
"chat.compactingManual": "Compacting the conversation",
|
||
"chat.compactingDetail": "{tokens} of {limit} tokens ({pct}) – the agent continues with a summary afterwards",
|
||
"chat.telegram": "Send questions to Telegram",
|
||
"chat.telegramHint": "Also send approvals and questions of this chat via Telegram (the chat currently open in Telegram always reports)",
|
||
"cron.label": "Schedule",
|
||
"cron.mode.minutes": "Every few minutes",
|
||
"cron.mode.hourly": "Hourly",
|
||
"cron.mode.daily": "Daily",
|
||
"cron.mode.weekly": "On weekdays",
|
||
"cron.mode.monthly": "Monthly",
|
||
"cron.mode.custom": "Cron expression",
|
||
"cron.every": "Every",
|
||
"cron.minutes": "minutes",
|
||
"cron.atMinute": "At minute",
|
||
"cron.days": "Days of the week",
|
||
"cron.workdays": "Mon–Fri",
|
||
"cron.onDay": "On day",
|
||
"cron.at": "at",
|
||
"cron.customHint": "Minute hour day month weekday, e.g. “30 6 * * 1-5” = Mon–Fri 06:30.",
|
||
"cron.nextRuns": "Next runs:",
|
||
"cron.shortMonths": "Months without this day are skipped.",
|
||
"cron.serverTz": "Times in server time ({tz})",
|
||
"jobEditor.saved": "Saved",
|
||
"jobEditor.conflict": "The instructions were changed on disk meanwhile (e.g. by the assistant). Overwrite them with your version?",
|
||
"jobEditor.overwrite": "Overwrite",
|
||
"jobEditor.runUnsaved": "There are unsaved changes – the run uses the saved version. Start anyway?",
|
||
"jobEditor.discard": "Discard the unsaved changes?",
|
||
"jobEditor.back": "Back to automations",
|
||
"jobEditor.tab.prompt": "Instructions",
|
||
"jobEditor.tab.settings": "Schedule",
|
||
"jobEditor.tab.assistant": "Assistant",
|
||
"jobEditor.timeout": "Time limit (min)",
|
||
"jobEditor.bypassHint": "Runs at night: with “Allow everything” the run never waits for approval.",
|
||
"jobEditor.instructions": "Instructions",
|
||
"jobEditor.instructionsHint": "The agent sees only this text – no chat, nobody to ask.",
|
||
"jobEditor.changedOnDisk": "The assistant changed the file while you were editing.",
|
||
"jobEditor.reload": "Load its version",
|
||
"jobEditor.assistantIntro": "Work out the instructions together with a model: describe what the automation should do – it asks back and writes the file next to you.",
|
||
"jobEditor.assistantStart": "Start assistant",
|
||
"jobEditor.defaultModel": "Server default",
|
||
"jobs.new": "New automation",
|
||
"jobs.namePlaceholder": "e.g. Nightly dependency check",
|
||
"jobs.fileHint": "The instructions go to .codecraft/jobs/<name>.md in this folder.",
|
||
"jobs.startWith": "Start with",
|
||
"jobs.blank": "Blank",
|
||
"jobs.blankDesc": "Example structure to fill in with the assistant",
|
||
"jobs.createAndEdit": "Create and edit",
|
||
"jobs.edit": "Edit",
|
||
"jobs.permissionMode": "Approval mode",
|
||
"jobs.permissionModeHint": "Applies from the next run. “Allow everything”: the run never asks and never waits for approval.",
|
||
"instructions.title": "Instructions for this chat",
|
||
"instructions.hint": "Apply to every message in this chat, in addition to the mode – e.g. language, tone, rules, the part of the project to work on.",
|
||
"instructions.placeholder": "e.g. Always answer in English. Only change files under api/. Ask before adding dependencies.",
|
||
"instructions.clear": "Remove",
|
||
"instructions.chip": "Instructions",
|
||
"chat.compacted": "Conversation compacted – summary",
|
||
"chat.context": "Context",
|
||
"chat.contextHint": "{tokens} tokens in the last request",
|
||
"chat.statsHint": "Tokens and cost of this session (click for details)",
|
||
"chat.renameHint": "Double-click to rename",
|
||
"chat.rewind": "Edit and resend from here",
|
||
"chat.delete": "Delete session",
|
||
"chat.deleteConfirm": "Delete this session including its subagents? Statistics are kept.",
|
||
|
||
"composer.placeholder": "Message… (/ for commands, @ for files, attach or paste files)",
|
||
"composer.placeholderBusy": "Message is queued and sent at the next step…",
|
||
"composer.send": "Send",
|
||
"composer.queue": "Queue",
|
||
"composer.stop": "Stop",
|
||
"composer.mode": "Mode",
|
||
"composer.model": "Model",
|
||
"composer.permissionMode": "Permission mode",
|
||
"composer.preview": "Preview (Markdown)",
|
||
"composer.previewEdit": "Back to editing",
|
||
"composer.previewEmpty": "Nothing to preview yet.",
|
||
"composer.attach": "Attach files",
|
||
|
||
"command.compact": "Summarize the conversation to free up context",
|
||
"command.new": "Start a new session",
|
||
|
||
"permissionMode.default": "Ask (except read-only commands)",
|
||
"permissionMode.accept_edits": "Auto-accept edits",
|
||
"permissionMode.bypass": "Allow everything",
|
||
|
||
"plan.implement": "Switch to build and implement the plan",
|
||
"plan.implementPrompt": "Implement the plan.",
|
||
|
||
"tool.input": "Input",
|
||
"tool.output": "Output",
|
||
"tool.todosUpdated": "Tasks updated ({done}/{total} done)",
|
||
"tool.todos": "Tasks",
|
||
"tool.openSubagent": "Open subagent session",
|
||
|
||
"interaction.fromSubagent": "From subagent:",
|
||
|
||
"permission.title": "Permission required",
|
||
"permission.allowOnce": "Allow once",
|
||
"permission.alwaysTool": "Always allow {tool} in this session",
|
||
"permission.alwaysCommand": "Always allow \"{prefix}\" in this session",
|
||
"permission.reject": "Reject",
|
||
"permission.rejectWithFeedback": "Reject with feedback",
|
||
"permission.feedback": "Optional: tell the agent what to do instead",
|
||
|
||
"question.title": "Question for you",
|
||
"question.fromAgent": "The agent needs a decision",
|
||
"question.fromMcp": "MCP server \"{server}\" asks",
|
||
"question.other": "Other (free text)",
|
||
"question.answer": "Your answer",
|
||
"question.submit": "Answer",
|
||
"question.dismiss": "Dismiss",
|
||
|
||
"settings.tab.general": "General",
|
||
"settings.tab.providers": "Providers & models",
|
||
"settings.tab.mcp": "MCP",
|
||
"settings.tab.permissions": "Permissions",
|
||
"settings.tab.agents": "Agents & commands",
|
||
"settings.tab.raw": "Config file",
|
||
"settings.saved": "Saved – changes are active.",
|
||
"settings.interface": "Interface (this device)",
|
||
"settings.language": "Language",
|
||
"settings.theme": "Theme",
|
||
"settings.themeMode": "Mode",
|
||
"settings.themeAuto": "Auto",
|
||
"settings.themeLight": "Light",
|
||
"settings.themeDark": "Dark",
|
||
"settings.themeSource": "Colours: {source} ({license})",
|
||
"settings.themeToggle": "Switch light/dark/auto",
|
||
"settings.notifications": "Notifications",
|
||
"settings.notificationsEnable": "Enable",
|
||
"settings.notificationsOn": "Enabled",
|
||
"settings.digest": "Daily cost summary at 20:00",
|
||
"settings.digestNow": "Send today's summary now",
|
||
"settings.pushTest": "Send test",
|
||
"settings.pushTestSent": "Test notification sent",
|
||
"settings.pushTestNone": "No device subscribed",
|
||
"settings.pushDisable": "Turn off",
|
||
"settings.pushUnsupported": "This browser does not support push notifications. On iPhone/iPad: add CodeCraft to the home screen first.",
|
||
"settings.pushDenied": "Notifications are blocked for this site – allow them in the browser settings.",
|
||
"settings.notificationsHint": "Push notifications on this device when an agent asks for permission, asks a question or finishes a longer task – only while CodeCraft is not open.",
|
||
"settings.server": "Server",
|
||
"settings.workspace": "Workspace",
|
||
"settings.defaultModel": "Default model",
|
||
"settings.smallModel": "Small model",
|
||
"settings.smallModelHint": "Used for session titles. Compaction uses the session model.",
|
||
"settings.currency": "Currency",
|
||
"settings.autoCompact": "Auto-compact at",
|
||
"settings.autoCompactHint": "Fraction of the context window (0 = off).",
|
||
"settings.craft": "Craft mode",
|
||
"settings.cleanRoom": "Clean room",
|
||
"settings.cleanRoomHint": "Only use what a visitor sees. Off = deep mode (page source and scripts may be read).",
|
||
"settings.chromium": "Chromium binary",
|
||
"settings.widths": "Screen widths (px)",
|
||
"settings.kind": "Type",
|
||
"settings.baseUrl": "Base URL",
|
||
"settings.apiKey": "API key",
|
||
"settings.apiKeyStored": "Stored – leave empty to keep",
|
||
"settings.apiKeyHint": "Stored in the configuration file (readable for admins, included in backups). ${NAME} references to environment variables still work.",
|
||
"settings.authPrefix": "Auth prefix",
|
||
"settings.enabled": "Enabled",
|
||
"settings.modelCount": "{n} models",
|
||
"settings.models": "Models & prices",
|
||
"settings.addModel": "Model",
|
||
"settings.addDiscovered": "Add {n} discovered",
|
||
"settings.pricesHint": "Prices per 1M tokens in the configured currency. Cache prices default to the input price.",
|
||
"settings.modelsEmptyHint": "No models listed: they are discovered automatically from the provider.",
|
||
"settings.context": "Context",
|
||
"settings.maxInput": "Max input",
|
||
"settings.maxInputHint": "Input limit, if the provider sets one below the context window (empty: the context window). The chat is compacted before the input reaches it.",
|
||
"settings.maxOutput": "Max output",
|
||
"settings.reasoning": "Reasoning",
|
||
"settings.vision": "Vision",
|
||
"settings.effort": "Effort",
|
||
"settings.priceIn": "Input",
|
||
"settings.priceOut": "Output",
|
||
"settings.priceCacheRead": "Cache read",
|
||
"settings.priceCacheWrite": "Cache write",
|
||
"settings.addProvider": "Add provider",
|
||
"settings.providerName": "Name (optional)",
|
||
"settings.providerUp": "reachable · {ms} ms",
|
||
"settings.providerDown": "unreachable",
|
||
"settings.testConnection": "Test connection",
|
||
"settings.testing": "Testing…",
|
||
"settings.testOk": "Connection works: {n} models, {ms} ms. Not saved yet.",
|
||
"settings.providerAuth": "API key missing or rejected",
|
||
"settings.providerCheck": "Check providers",
|
||
"settings.providerChecking": "Checking…",
|
||
"settings.reloadProviders": "Reload providers & models",
|
||
"settings.deleteProviderConfirm": "Delete provider \"{name}\"?",
|
||
"settings.invalidName": "Names may only contain letters, digits, - and _.",
|
||
"settings.name": "Name",
|
||
"settings.addMcp": "Add MCP server",
|
||
"settings.deleteMcpConfirm": "Delete MCP server \"{name}\"?",
|
||
"settings.rawHint": "The complete configuration file including comments. It is validated before saving.",
|
||
"settings.revert": "Revert",
|
||
|
||
"mcp.load": "Tools for the model",
|
||
"mcp.loadAuto": "Automatic (on demand when many tools)",
|
||
"mcp.loadAlways": "Always send all tools",
|
||
"mcp.loadOnDemand": "On demand (mcp_search / mcp_call)",
|
||
"mcp.loadHint": "Every tool sent directly costs context on every request. Large servers are better loaded on demand.",
|
||
"mcp.reconnect": "Reconnect all",
|
||
"mcp.none": "No MCP servers configured.",
|
||
"mcp.tools": "{n} tools",
|
||
"mcp.command": "Command",
|
||
"mcp.args": "Arguments (one per line)",
|
||
"mcp.env": "Environment (KEY=value)",
|
||
"mcp.headers": "Headers (Name: value)",
|
||
"mcp.state.disabled": "disabled",
|
||
"mcp.state.connecting": "connecting…",
|
||
"mcp.state.connected": "connected",
|
||
"mcp.state.failed": "failed",
|
||
"mcp.state.unknown": "not started",
|
||
|
||
"permissions.intro": "Rules for tool use. \"Ask\" shows an approval card. MCP tools: mcp__<server>__<tool>, wildcards allowed (mcp__*).",
|
||
"permissions.tools": "Tools",
|
||
"permissions.bash": "Shell commands",
|
||
"permissions.bashHint": "Glob patterns on the full command. Compound commands (&&, ;, |) are only allowed if every part is.",
|
||
"permissions.tool": "Tool",
|
||
"permissions.pattern": "Pattern",
|
||
"permissions.rule": "Rule",
|
||
"permissions.allow": "Allow",
|
||
"permissions.ask": "Ask",
|
||
"permissions.deny": "Deny",
|
||
|
||
"agents.title": "Agents",
|
||
"agents.readOnly": "read-only",
|
||
"agents.commands": "Slash commands",
|
||
"agents.skills": "Skills",
|
||
|
||
"stats.range7": "7 days",
|
||
"stats.range30": "30 days",
|
||
"stats.range90": "90 days",
|
||
"stats.range365": "1 year",
|
||
"stats.rangeAll": "All",
|
||
"stats.tableView": "Table view",
|
||
"stats.chartView": "Chart view",
|
||
"stats.cost": "Cost",
|
||
"stats.perRequest": "{v} per request",
|
||
"stats.requests": "Requests",
|
||
"stats.errors": "{n} failed",
|
||
"stats.input": "Input",
|
||
"stats.output": "Output",
|
||
"stats.cacheRead": "Cache read",
|
||
"stats.cacheHit": "Cache hit rate",
|
||
"stats.tokens": "Tokens",
|
||
"stats.ttft": "Time to first token",
|
||
"stats.ttftHint": "Average prefill wait",
|
||
"stats.outputSpeed": "Output speed",
|
||
"stats.prefillSpeed": "Prefill speed",
|
||
"stats.costPerDay": "Cost per day by model",
|
||
"stats.tokensPerDay": "Tokens per day",
|
||
"stats.heatEmpty": "no activity",
|
||
"stats.heatmap": "Activity of the last 14 days by hour",
|
||
"stats.byModel": "By model",
|
||
"stats.byProvider": "By provider",
|
||
"stats.byAgent": "By mode",
|
||
"stats.topSessions": "Most expensive sessions",
|
||
"stats.perDay": "Per day",
|
||
"stats.day": "Day",
|
||
"stats.model": "Model",
|
||
"stats.provider": "Provider",
|
||
"stats.agent": "Mode",
|
||
"stats.session": "Session",
|
||
"stats.total": "Total",
|
||
"stats.other": "Other",
|
||
"stats.noData": "No requests in this period.",
|
||
|
||
"common.ok": "OK",
|
||
"common.cancel": "Cancel",
|
||
"common.refresh": "Refresh",
|
||
"nav.logout": "Sign out",
|
||
"login.username": "Username",
|
||
"login.password": "Password",
|
||
"login.passwordRepeat": "Repeat password",
|
||
"login.setupPrompt": "No users yet. Enter the setup code from the server log and create the first admin.",
|
||
"login.setupCode": "Setup code",
|
||
"login.createAdmin": "Create admin",
|
||
"login.invalidCode": "Invalid setup code.",
|
||
"login.mismatch": "The passwords do not match.",
|
||
"login.or": "or",
|
||
"sidebar.shared": "Shared with you",
|
||
"chat.readOnly": "read-only",
|
||
"chat.readOnlyHint": "This session was shared with you – you can follow it, but not write.",
|
||
"chat.backgroundDone": "Background task finished",
|
||
"chat.waitingModel": "Waiting for a free slot on {model}…",
|
||
"chat.waitingSubagent": "Waiting for a free subagent slot ({agent})…",
|
||
"chat.anySubagent": "limit for all subagents",
|
||
"tool.background": "background",
|
||
"share.title": "Share session",
|
||
"share.hint": "Selected users can follow this session read-only.",
|
||
"share.noUsers": "No other users.",
|
||
"settings.tab.users": "Users",
|
||
"settings.tab.folders": "Shared folders",
|
||
"settings.tab.account": "Account",
|
||
"settings.maxParallelSubagents": "Parallel subagents",
|
||
"settings.maxParallelSubagentsHint": "Max. subagents running at the same time across all sessions (0 = unlimited).",
|
||
"settings.maxConcurrency": "Parallel requests",
|
||
"settings.maxConcurrencyHint": "Max. simultaneous requests to this host/model; more wait in a queue. 1 for servers that process one request at a time.",
|
||
"settings.slots": "Slots",
|
||
"account.title": "Account",
|
||
"account.current": "Current password",
|
||
"account.new": "New password",
|
||
"account.change": "Change password",
|
||
"account.changed": "Password changed. Other devices were signed out.",
|
||
"account.hint": "At least 8 characters.",
|
||
"users.intro": "Users work in their own folder <workspace>/<username> plus the folders shared with them. Admins can use the whole workspace and manage the server.",
|
||
"users.username": "Username",
|
||
"users.usernameHint": "Letters, digits, - _ . – also the name of the user's folder.",
|
||
"users.displayName": "Display name",
|
||
"users.role": "Role",
|
||
"users.roleUser": "User",
|
||
"users.roleAdmin": "Admin",
|
||
"users.login": "Sign-in",
|
||
"users.password": "Password",
|
||
"users.passwordHint": "Leave empty for single sign-on only.",
|
||
"users.created": "Created",
|
||
"users.you": "you",
|
||
"users.setPassword": "Set password",
|
||
"users.newPasswordFor": "New password for {name} (min. 8 characters):",
|
||
"users.enable": "Enable",
|
||
"users.disable": "Disable",
|
||
"users.deleteConfirm": "Delete user \"{name}\"? Their sessions stay visible to admins.",
|
||
"users.add": "Add user",
|
||
"folders.intro": "Folders inside the workspace that selected users may work in, in addition to their own folder.",
|
||
"folders.none": "No shared folders yet.",
|
||
"folders.noUsers": "No users without admin role.",
|
||
"folders.add": "Share a folder",
|
||
"folders.addHint": "The folder is created if it does not exist. Existing project folders can be shared too.",
|
||
"folders.remove": "Stop sharing",
|
||
"folders.removeConfirm": "Stop sharing this folder? The files are kept.",
|
||
"agents.intro": "Modes and subagents with their model. A subagent can run on another model or host – e.g. a small model that writes docs or translations in the background.",
|
||
"agents.primaryTitle": "Modes",
|
||
"agents.subagentTitle": "Subagents",
|
||
"agents.modePrimary": "mode",
|
||
"agents.modeSubagent": "subagent",
|
||
"agents.source.builtin": "built-in",
|
||
"agents.source.personal": "personal",
|
||
"agents.source.config": "config",
|
||
"agents.source.file": "file",
|
||
"agents.model": "Model",
|
||
"agents.sessionModel": "Session model",
|
||
"agents.modelHint": "Fixed model for this agent; empty = the model selected in the chat.",
|
||
"agents.maxParallel": "Max. parallel",
|
||
"agents.maxParallelShort": "max. {n} parallel",
|
||
"agents.description": "Description",
|
||
"agents.descriptionHint": "The main agent decides by this description when to delegate.",
|
||
"agents.mode": "Type",
|
||
"agents.addMode": "New mode",
|
||
"agents.style": "Kind",
|
||
"agents.styleCoding": "Coding – project context and coding workflow",
|
||
"agents.styleChat": "Conversation – only this prompt, no project",
|
||
"agents.styleHint": "Conversation modes get just your prompt plus date and personal memory, like the built-in chat mode.",
|
||
"agents.readOnlyLabel": "Read-only",
|
||
"agents.readOnlyHint": "Only tools that change nothing (like plan mode)",
|
||
"agents.toolsSome": "{n} tools selected – only these are available",
|
||
"agents.tools": "Tools",
|
||
"agents.toolsAll": "Nothing selected = all tools",
|
||
"agents.prompt": "Instructions",
|
||
"agents.reset": "Reset",
|
||
"agents.resetConfirm": "Reset \"{name}\" to the built-in defaults?",
|
||
"agents.deleteConfirm": "Delete agent \"{name}\"?",
|
||
"agents.add": "Add agent",
|
||
"agents.addWriter": "Writer (docs, summaries, translations)",
|
||
"agents.addBlank": "Empty agent",
|
||
"stats.user": "User",
|
||
"stats.allUsers": "All users",
|
||
"stats.byUser": "By user",
|
||
};
|
||
|
||
export type Messages = Record<keyof typeof en, string>;
|