feat: complete Epic 1 production foundation

This commit is contained in:
2026-08-25 01:24:11 +03:00
parent 767428436d
commit 182bde8ac0
298 changed files with 35719 additions and 5299 deletions
+312 -2
View File
@@ -20,6 +20,43 @@ var TRANSLATIONS = {
'nav.user_fallback': 'Crank',
'nav.workspace_fallback': 'workspace',
'onboarding.title': 'Getting Started',
'onboarding.subtitle': 'A resumable path to your first real MCP tool call.',
'onboarding.loading': 'Checking authoritative progress…',
'onboarding.progress': '{count}/7 steps complete',
'onboarding.error': 'Getting Started progress is unavailable.',
'onboarding.retry': 'Retry',
'onboarding.refresh': 'Refresh progress',
'onboarding.dismiss': 'Dismiss',
'onboarding.resume': 'Resume Getting Started',
'onboarding.collapse': 'Collapse Getting Started checklist',
'onboarding.request_id': 'Request ID',
'onboarding.trace_id': 'Trace ID',
'onboarding.error_code': 'Error code',
'onboarding.progress_label': 'Getting Started progress',
'onboarding.action_needed': 'This is the next actionable step.',
'onboarding.regressed': 'The referenced object changed. Review and continue again.',
'onboarding.completed': 'Your first public MCP tool call is complete.',
'onboarding.open_invocation': 'Open invocation history',
'onboarding.tool': 'Tool',
'onboarding.timestamp': 'Timestamp',
'onboarding.deep_link_stale': 'This onboarding link references a changed Operation or Agent. Reset it and reselect the current published revision.',
'onboarding.reselect': 'Reset and reselect',
'onboarding.step.operation': 'Create an Operation',
'onboarding.step.test': 'Test the Operation',
'onboarding.step.publish_operation': 'Publish the Operation',
'onboarding.step.agent': 'Create and publish an Agent',
'onboarding.step.key': 'Create an MCP client key',
'onboarding.step.mcp_connection': 'Connect an MCP client',
'onboarding.step.first_call': 'Make the first tool call',
'onboarding.action.operation': 'Create Operation',
'onboarding.action.test': 'Open test',
'onboarding.action.publish_operation': 'Open publication',
'onboarding.action.agent': 'Create Agent',
'onboarding.action.key': 'Create key',
'onboarding.action.mcp_connection': 'Show connection',
'onboarding.action.first_call': 'Open Logs',
// Operations page
'ops.title': 'Operations',
'ops.subtitle': 'Catalog of tools. List of created MCP tools for API endpoints.',
@@ -37,6 +74,12 @@ var TRANSLATIONS = {
'ops.delete.error.message': 'Failed to delete operation',
'ops.action.edit': 'Edit operation',
'ops.action.delete':'Delete operation',
'ops.action.archive': 'Archive operation',
'ops.archive.confirm': 'Archive this operation? Existing published Agent snapshots remain available, but new publications and bindings will be blocked.',
'ops.archive.success.title': 'Operation archived',
'ops.archive.success.message': '{name} was archived.',
'ops.archive.error.title': 'Archive failed',
'ops.archive.error.message': 'Failed to archive operation',
'ops.stats.synced': 'Catalog synced with backend',
'ops.stats.none': 'No operations yet',
'ops.stats.share': '{value}% of total',
@@ -137,11 +180,16 @@ var TRANSLATIONS = {
'apikeys.modal.reveal_title': 'Copy this key now.',
'apikeys.modal.reveal_body': "It won't be shown again.",
'apikeys.modal.copy': 'Copy to clipboard',
'apikeys.modal.copy_config': 'Copy configuration',
'apikeys.modal.connection_title': 'MCP connection configuration',
'apikeys.modal.clipboard_warning': 'Your operating system clipboard is outside Crank control. Clear it after saving the key.',
'apikeys.onboarding.key_lost': 'The key cannot be shown again. Create a new key and revoke the old one if its value was not saved.',
'apikeys.modal.cancel': 'Cancel',
'apikeys.modal.create': 'Create key',
'apikeys.modal.done': "Done — I've copied the key",
'apikeys.status.active': 'Active',
'apikeys.status.revoked': 'Revoked',
'apikeys.status.deleted': 'Deleted',
'apikeys.last_used.never': 'Never',
'apikeys.empty.none': 'No API keys yet',
'apikeys.empty.approval': 'No approval keys yet. Create one only if this agent has tools that require human confirmation.',
@@ -167,12 +215,18 @@ var TRANSLATIONS = {
'apikeys.toast.create_error_message': 'Failed to create key',
'apikeys.toast.copy_title': 'Agent key copied',
'apikeys.toast.copy_message': 'Store the raw key securely. It cannot be revealed again.',
'apikeys.toast.copy_error_title': 'Clipboard write failed',
'apikeys.toast.copy_error_message': 'The one-time value is still visible. Copy it manually before closing this page.', // community-scope: allow=one-time-token
'apikeys.toast.prefix_title': 'Key prefix copied',
'apikeys.action.copy_prefix': 'Copy key prefix',
'apikeys.action.revoke': 'Revoke key',
'apikeys.action.delete': 'Delete',
'apikeys.creating': 'Creating…',
'apikeys.approval.warning': 'Do not pass this key to an LLM or MCP client. It is only for an external interface where a human confirms an action.',
'apikeys.ambiguous.title': 'Creation result is uncertain.',
'apikeys.ambiguous.body': 'Key metadata was refreshed. Review the list before deliberately creating another key.',
'apikeys.ambiguous.retry': 'Refresh metadata and allow another attempt',
'apikeys.ambiguous.blocked': 'Review metadata before retrying',
// Secrets page
'secrets.title': 'Secrets',
@@ -256,6 +310,16 @@ var TRANSLATIONS = {
'logs.live': 'Live',
'logs.paused': 'Paused',
'logs.refresh': 'Refresh',
'logs.export': 'Export CSV',
'logs.load_more': 'Load more',
'logs.status_filter': 'Status',
'logs.status.all': 'All statuses',
'logs.status.ok': 'Success',
'logs.status.error': 'Error',
'logs.outcome_filter': 'Outcome',
'logs.outcome.all': 'All outcomes',
'logs.filter.operation': 'Operation ID',
'logs.filter.agent': 'Agent ID',
'logs.range.30m': 'Last 30 min',
'logs.range.1h': 'Last hour',
'logs.range.6h': 'Last 6 hours',
@@ -281,6 +345,10 @@ var TRANSLATIONS = {
'logs.live.off.body': 'Automatic polling is paused.',
'logs.refresh.title': 'Logs refreshed',
'logs.refresh.body': 'The latest invocation records were loaded for the current workspace.',
'logs.export.done_title': 'Logs exported',
'logs.export.done_body': 'The filtered invocation history was exported as CSV.',
'logs.export.error_title': 'Export failed',
'logs.export.error_body': 'Failed to export invocation history.',
'approvals.title': 'Human confirmations',
'approvals.subtitle': 'Requests waiting for an external user decision and recent results.',
'approvals.refresh': 'Refresh',
@@ -289,6 +357,7 @@ var TRANSLATIONS = {
'approvals.loading': 'Loading confirmation requests…',
'approvals.empty': 'There are no confirmation requests yet.',
'approvals.error.load': 'Failed to load confirmation requests',
'approvals.error.decision': 'Failed to submit confirmation decision',
'approvals.untitled': 'Confirmation request',
'approvals.operation': 'Operation',
'approvals.agent': 'Agent',
@@ -296,6 +365,13 @@ var TRANSLATIONS = {
'approvals.updated_at': 'Updated',
'approvals.request': 'Request',
'approvals.response': 'Result',
'approvals.request_id': 'Request ID',
'approvals.trace_id': 'Trace ID',
'approvals.action.approve': 'Approve',
'approvals.action.deny': 'Deny',
'approvals.action.busy': 'Submitting…',
'approvals.confirm.approve': 'Approve this pending confirmation request?',
'approvals.confirm.deny': 'Deny this pending confirmation request?',
'approvals.status.pending': 'Pending',
'approvals.status.approved': 'Approved',
'approvals.status.denied': 'Denied',
@@ -328,6 +404,19 @@ var TRANSLATIONS = {
'usage.chart.error': 'Error',
'usage.chart.empty.title': 'No usage data yet',
'usage.chart.empty.sub': 'Invocation metrics will appear here after tests or published tool calls in the selected period.',
'usage.outcomes.title': 'Outcomes',
'usage.outcomes.subtitle': 'Grouped by safe execution outcome.',
'usage.outcomes.empty.title': 'No outcome breakdown yet',
'usage.outcomes.empty.sub': 'Outcome groups will appear after invocations are recorded.',
'usage.outcomes.p50': 'p50',
'usage.outcomes.p95': 'p95',
'usage.outcomes.p99': 'p99',
'usage.outcome.success': 'Success',
'usage.outcome.upstream': 'Upstream',
'usage.outcome.client': 'Client',
'usage.outcome.schema': 'Schema',
'usage.outcome.crank': 'Crank',
'usage.outcome.no_error_code': 'No error code',
'usage.table.title': 'By operation',
'usage.table.subtitle': 'Breakdown for {period}',
'usage.table.th.operation': 'Operation',
@@ -349,7 +438,9 @@ var TRANSLATIONS = {
'usage.export.empty.title': 'No usage data loaded',
'usage.export.empty.body': 'Load usage data before exporting the CSV snapshot.',
'usage.export.done.title': 'Usage exported',
'usage.export.done.body': 'The current usage snapshot was exported as CSV.',
'usage.export.done.body': 'The filtered usage dataset was exported as CSV.',
'usage.export.error.title': 'Export failed',
'usage.export.error.body': 'Failed to export usage data.',
'usage.chart.ok': '{count} ok',
'usage.chart.errors': '{count} errors',
'usage.chart.week': 'Wk {index}',
@@ -403,6 +494,7 @@ var TRANSLATIONS = {
'settings.security.change_password': 'Change password',
'settings.security.mismatch': 'New password and confirmation do not match.',
'settings.security.saved': 'Password updated.',
'settings.security.saved_relogin': 'Password updated. Please sign in again.',
'settings.security.save_error': 'Failed to change password',
'settings.capability.rest': 'REST / HTTP',
'settings.capability.standard': 'standard',
@@ -706,6 +798,36 @@ var TRANSLATIONS = {
'wizard.test.failed': 'Operation test returned errors',
'wizard.test.completed_body': 'The operation was executed successfully against the API.',
'wizard.test.failed_body': 'The operation was executed, but the API or validation returned errors.',
'execution.error.authorization_denied': 'Operation execution is denied.',
'execution.error.auth_profile_not_found': 'Authorization profile was not found.',
'execution.error.secret_not_found': 'Authorization secret was not found.',
'execution.error.secret_invalid': 'Authorization secret has an invalid format.',
'execution.error.input_schema_invalid': 'Input does not satisfy the operation schema.',
'execution.error.input_mapping_invalid': 'Input parameters could not be mapped.',
'execution.error.prepared_request_invalid': 'A valid upstream request could not be prepared.',
'execution.error.execution_overloaded': 'The service is temporarily overloaded.',
'execution.error.safety_store_unavailable': 'A mandatory safety store is unavailable.',
'execution.error.protocol_unsupported': 'The operation protocol is unsupported.',
'execution.error.execution_mode_unsupported': 'The execution mode is unsupported.',
'execution.error.adapter_configuration_invalid': 'The adapter configuration is invalid.',
'execution.error.outbound_target_rejected': 'The target was rejected by the safety policy.',
'execution.error.upstream_auth_error': 'The upstream API rejected authorization.',
'execution.error.upstream_not_found': 'The upstream resource was not found.',
'execution.error.upstream_rate_limited': 'The upstream API rate-limited the request.',
'execution.error.upstream_server_error': 'The upstream API is temporarily unavailable.',
'execution.error.upstream_status_error': 'The upstream API returned an error status.',
'execution.error.upstream_timeout': 'The upstream API timed out.',
'execution.error.upstream_transport_error': 'The upstream API could not be reached.',
'execution.error.upstream_response_too_large': 'The upstream response exceeded its limit.',
'execution.error.output_mapping_invalid': 'The upstream response could not be mapped.',
'execution.error.output_schema_invalid': 'The output does not satisfy the operation schema.',
'execution.error.persistence_unavailable': 'Mandatory result persistence is unavailable.',
'execution.error.runtime_internal': 'Internal execution failure.',
'execution.error.confirmation_required': 'The operation requires confirmation.',
'execution.error.confirmation_invalid': 'The confirmation is invalid or expired.',
'execution.error.idempotency_in_progress': 'The operation is already running for this key.',
'execution.error.idempotency_conflict': 'The idempotency key was used with different input.',
'execution.error.idempotency_outcome_unknown': 'The previous outcome is unknown; automatic retry is unsafe.',
'wizard.test.window_completed': 'Window test completed',
'wizard.test.window_completed_body': 'Collected a bounded result window.',
'wizard.test.window_truncated_note': 'Results were truncated.',
@@ -727,6 +849,7 @@ var TRANSLATIONS = {
'wizard.quality.blocked_title': 'Quality check found blocking issues',
'wizard.quality.blocked_body': 'Fix error-level findings before publishing.',
'wizard.quality.blocking_error': 'Fix blocking quality findings before publishing.',
'wizard.quality.import_findings_hint': 'These findings came from OpenAPI import. Run quality analysis to recalculate them for the current Draft.',
'wizard.quality.severity_error': 'Error',
'wizard.quality.severity_warning': 'Warning',
'wizard.quality.severity_info': 'Info',
@@ -743,6 +866,16 @@ var TRANSLATIONS = {
'wizard.yaml.loaded_body': 'The YAML configuration was loaded.',
'wizard.publish.done': 'Operation published',
'wizard.publish.done_body': 'Version {version} is now published and can be bound into agents.',
'wizard.publish.confirm': 'Publish the saved Draft as a new immutable version?',
'wizard.stale.title': 'Draft changed elsewhere',
'wizard.stale.body': 'Your edits are preserved in this browser. Reload the latest saved Draft before retrying.',
'wizard.test.correlation': 'Request ID: {requestId}\nTrace ID: {traceId}',
'wizard.test.request_id': 'Request ID',
'wizard.test.trace_id': 'Trace ID',
'wizard.test.copy_request_id': 'Copy Request ID',
'wizard.test.copy_trace_id': 'Copy Trace ID',
'wizard.test.id_copied': 'Support ID copied',
'wizard.test.id_copied_body': 'The identifier was copied without request or response payload.',
// Common buttons
'btn.save': 'Save changes',
@@ -785,6 +918,7 @@ var TRANSLATIONS = {
'agents.card.keys': 'keys',
'agents.card.calls_today': 'calls today',
'agents.card.created': 'Created {date}',
'agents.card.revision': 'Draft v{draft} · Published v{published} · Catalog rev {revision}',
'agents.card.copy_endpoint': 'Copy endpoint',
'agents.card.endpoint_help': 'Set this endpoint in the MCP client together with the API key.',
'agents.card.endpoint_help_community': 'Set this endpoint in the MCP client together with the API key.',
@@ -809,6 +943,7 @@ var TRANSLATIONS = {
'agents.drawer.optional': '(optional)',
'agents.drawer.required': 'required',
'agents.drawer.status': 'Status',
'agents.drawer.revision': 'Draft v{draft} · Published v{published} · Catalog rev {revision}',
'agents.drawer.endpoint': 'MCP endpoint',
'agents.drawer.slug_hint': 'Slug is used as part of the endpoint to identify the agent.',
'agents.drawer.placeholder.name': 'Customer Support',
@@ -867,12 +1002,17 @@ var TRANSLATIONS = {
'agents.toast.delete_message': '{name} was deleted.',
'agents.toast.delete_error_title': 'Delete failed',
'agents.toast.delete_error_message': 'Failed to delete agent',
'agents.toast.delete_forbidden_message': 'Published agents cannot be deleted. Archive or unpublish the agent first.',
'agents.toast.lifecycle_title': 'Agent lifecycle updated',
'agents.toast.lifecycle_publish_confirm': 'Publish {name}? The published MCP catalog will change.',
'agents.toast.lifecycle_unpublish_confirm': 'Unpublish {name}? Existing MCP clients will no longer see this agent catalog.',
'agents.toast.lifecycle_archive_confirm': 'Archive {name}? New publications and bindings will be blocked.',
'agents.toast.lifecycle_publish': '{name} was published.',
'agents.toast.lifecycle_unpublish': '{name} was returned to draft.',
'agents.toast.lifecycle_archive': '{name} was archived.',
'agents.toast.lifecycle_error_title': 'Lifecycle update failed',
'agents.toast.lifecycle_error_message': 'Failed to update agent lifecycle',
'agents.toast.stale_message': 'Agent changed in another request. Reload the drawer and retry.',
'agents.toast.endpoint_title': 'MCP endpoint copied',
// Demo content
@@ -889,9 +1029,24 @@ var TRANSLATIONS = {
'login.email_label': 'Email address',
'login.email_placeholder': 'you@acme.com',
'login.password_only': 'Sign in with email and password.',
'login.bootstrap.title': 'Create admin account',
'login.bootstrap.subtitle': 'Complete local first-run bootstrap',
'login.bootstrap.note': 'Enter the one-time token generated by crank-migrate and choose the first admin password.', // community-scope: allow=one-time-token
'login.bootstrap.token_label': 'Bootstrap token',
'login.bootstrap.token_placeholder': 'Paste one-time bootstrap token', // community-scope: allow=one-time-token
'login.bootstrap.submit': 'Create admin',
'login.loading': 'Signing in…',
'login.success': 'Signed in. Redirecting…',
'login.bootstrap.loading': 'Creating admin…',
'login.bootstrap.success': 'Admin account created. Redirecting…',
'login.error.required': 'Please enter your email and password.',
'login.bootstrap.error.required': 'Please enter the bootstrap token and password.',
'login.error.invalid': 'Invalid email or password. Please try again.',
'login.error.throttled': 'Too many attempts. Please wait and try again.',
'login.error.expired_session': 'Your session expired. Please sign in again.',
'login.error.generic': 'Unable to sign in right now. Please try again.',
'login.error.request_id': 'Request ID',
'login.error.trace_id': 'Trace ID',
},
ru: {
@@ -910,6 +1065,43 @@ var TRANSLATIONS = {
'nav.user_fallback': 'Crank',
'nav.workspace_fallback': 'workspace',
'onboarding.title': 'Начало работы',
'onboarding.subtitle': 'Возобновляемый путь к первому реальному вызову MCP-инструмента.',
'onboarding.loading': 'Проверяем подтверждённый прогресс…',
'onboarding.progress': 'Выполнено шагов: {count}/7',
'onboarding.error': 'Прогресс начала работы недоступен.',
'onboarding.retry': 'Повторить',
'onboarding.refresh': 'Обновить прогресс',
'onboarding.dismiss': 'Скрыть',
'onboarding.resume': 'Продолжить начало работы',
'onboarding.collapse': 'Свернуть чек-лист начала работы',
'onboarding.request_id': 'Request ID',
'onboarding.trace_id': 'Trace ID',
'onboarding.error_code': 'Код ошибки',
'onboarding.progress_label': 'Прогресс начала работы',
'onboarding.action_needed': 'Это следующий доступный шаг.',
'onboarding.regressed': 'Связанный объект изменился. Проверьте его и продолжите снова.',
'onboarding.completed': 'Первый публичный вызов MCP-инструмента выполнен.',
'onboarding.open_invocation': 'Открыть историю вызова',
'onboarding.tool': 'Инструмент',
'onboarding.timestamp': 'Время вызова',
'onboarding.deep_link_stale': 'Эта ссылка начала работы относится к изменённой операции или агенту. Сбросьте её и выберите актуальную опубликованную ревизию.',
'onboarding.reselect': 'Сбросить и выбрать заново',
'onboarding.step.operation': 'Создать операцию',
'onboarding.step.test': 'Протестировать операцию',
'onboarding.step.publish_operation': 'Опубликовать операцию',
'onboarding.step.agent': 'Создать и опубликовать агента',
'onboarding.step.key': 'Создать ключ MCP-клиента',
'onboarding.step.mcp_connection': 'Подключить MCP-клиент',
'onboarding.step.first_call': 'Выполнить первый вызов',
'onboarding.action.operation': 'Создать операцию',
'onboarding.action.test': 'Открыть тест',
'onboarding.action.publish_operation': 'Открыть публикацию',
'onboarding.action.agent': 'Создать агента',
'onboarding.action.key': 'Создать ключ',
'onboarding.action.mcp_connection': 'Показать подключение',
'onboarding.action.first_call': 'Открыть логи',
// Operations page
'ops.title': 'Операции',
'ops.subtitle': 'Каталог инструментов. Список созданных MCP инструментов на API эндпоинты.',
@@ -927,6 +1119,12 @@ var TRANSLATIONS = {
'ops.delete.error.message': 'Не удалось удалить операцию',
'ops.action.edit': 'Редактировать операцию',
'ops.action.delete':'Удалить операцию',
'ops.action.archive': 'Архивировать операцию',
'ops.archive.confirm': 'Архивировать операцию? Существующие опубликованные снимки агентов останутся доступны, но новые публикации и привязки будут запрещены.',
'ops.archive.success.title': 'Операция архивирована',
'ops.archive.success.message': 'Операция {name} архивирована.',
'ops.archive.error.title': 'Не удалось архивировать',
'ops.archive.error.message': 'Не удалось архивировать операцию',
'ops.stats.synced': 'Каталог синхронизирован с сервером',
'ops.stats.none': 'Операций пока нет',
'ops.stats.share': '{value}% от общего числа',
@@ -1027,11 +1225,16 @@ var TRANSLATIONS = {
'apikeys.modal.reveal_title': 'Скопируйте ключ сейчас.',
'apikeys.modal.reveal_body': 'Повторно он не будет показан.',
'apikeys.modal.copy': 'Скопировать',
'apikeys.modal.copy_config': 'Скопировать конфигурацию',
'apikeys.modal.connection_title': 'Конфигурация MCP-подключения',
'apikeys.modal.clipboard_warning': 'Системный буфер обмена находится вне контроля Crank. Очистите его после сохранения ключа.',
'apikeys.onboarding.key_lost': 'Ключ нельзя показать повторно. Создайте новый ключ и отзовите старый, если значение не было сохранено.',
'apikeys.modal.cancel': 'Отмена',
'apikeys.modal.create': 'Создать ключ',
'apikeys.modal.done': 'Готово — ключ скопирован',
'apikeys.status.active': 'Активен',
'apikeys.status.revoked': 'Отозван',
'apikeys.status.deleted': 'Удален',
'apikeys.last_used.never': 'Никогда',
'apikeys.empty.none': 'API-ключей пока нет',
'apikeys.empty.approval': 'Ключей подтверждения пока нет. Они нужны только агентам с инструментами, требующими подтверждения человеком.',
@@ -1057,12 +1260,18 @@ var TRANSLATIONS = {
'apikeys.toast.create_error_message': 'Не удалось создать ключ',
'apikeys.toast.copy_title': 'Ключ агента скопирован',
'apikeys.toast.copy_message': 'Сохраните исходный ключ в надежном месте. Повторно показать его нельзя.',
'apikeys.toast.copy_error_title': 'Не удалось записать в буфер обмена',
'apikeys.toast.copy_error_message': 'Одноразовое значение всё ещё показано. Скопируйте его вручную до закрытия страницы.',
'apikeys.toast.prefix_title': 'Префикс ключа скопирован',
'apikeys.action.copy_prefix': 'Скопировать префикс ключа',
'apikeys.action.revoke': 'Отозвать ключ',
'apikeys.action.delete': 'Удалить',
'apikeys.creating': 'Создание…',
'apikeys.approval.warning': 'Не передавайте этот ключ LLM или MCP-клиенту. Он нужен только внешнему интерфейсу, где человек подтверждает действие.',
'apikeys.ambiguous.title': 'Результат создания неизвестен.',
'apikeys.ambiguous.body': 'Метаданные ключей обновлены. Проверьте список перед осознанным созданием ещё одного ключа.',
'apikeys.ambiguous.retry': 'Обновить метаданные и разрешить новую попытку',
'apikeys.ambiguous.blocked': 'Проверьте метаданные перед повтором',
// Secrets page
'secrets.title': 'Секреты',
@@ -1148,6 +1357,16 @@ var TRANSLATIONS = {
'logs.live': 'Live',
'logs.paused': 'Пауза',
'logs.refresh': 'Обновить',
'logs.export': 'Экспорт CSV',
'logs.load_more': 'Загрузить ещё',
'logs.status_filter': 'Статус',
'logs.status.all': 'Все статусы',
'logs.status.ok': 'Успех',
'logs.status.error': 'Ошибка',
'logs.outcome_filter': 'Результат',
'logs.outcome.all': 'Все результаты',
'logs.filter.operation': 'ID операции',
'logs.filter.agent': 'ID агента',
'logs.range.30m': 'Последние 30 мин',
'logs.range.1h': 'Последний час',
'logs.range.6h': 'Последние 6 часов',
@@ -1173,6 +1392,10 @@ var TRANSLATIONS = {
'logs.live.off.body': 'Автоматический опрос остановлен.',
'logs.refresh.title': 'Логи обновлены',
'logs.refresh.body': 'Получены последние записи вызовов для текущего воркспейса.',
'logs.export.done_title': 'Логи экспортированы',
'logs.export.done_body': 'Отфильтрованная история вызовов экспортирована в CSV.',
'logs.export.error_title': 'Не удалось экспортировать',
'logs.export.error_body': 'Не удалось экспортировать историю вызовов.',
'approvals.title': 'Подтверждения человеком',
'approvals.subtitle': 'Заявки, которые ожидают решения пользователя, и последние результаты.',
'approvals.refresh': 'Обновить',
@@ -1181,6 +1404,7 @@ var TRANSLATIONS = {
'approvals.loading': 'Загрузка заявок на подтверждение…',
'approvals.empty': 'Заявок на подтверждение пока нет.',
'approvals.error.load': 'Не удалось загрузить заявки на подтверждение',
'approvals.error.decision': 'Не удалось отправить решение по заявке',
'approvals.untitled': 'Заявка на подтверждение',
'approvals.operation': 'Операция',
'approvals.agent': 'Агент',
@@ -1188,6 +1412,13 @@ var TRANSLATIONS = {
'approvals.updated_at': 'Обновлено',
'approvals.request': 'Запрос',
'approvals.response': 'Результат',
'approvals.request_id': 'Request ID',
'approvals.trace_id': 'Trace ID',
'approvals.action.approve': 'Подтвердить',
'approvals.action.deny': 'Отклонить',
'approvals.action.busy': 'Отправка…',
'approvals.confirm.approve': 'Подтвердить эту заявку?',
'approvals.confirm.deny': 'Отклонить эту заявку?',
'approvals.status.pending': 'Ожидает',
'approvals.status.approved': 'Подтверждено',
'approvals.status.denied': 'Отклонено',
@@ -1220,6 +1451,19 @@ var TRANSLATIONS = {
'usage.chart.error': 'Ошибка',
'usage.chart.empty.title': 'Данных по использованию пока нет',
'usage.chart.empty.sub': 'Метрики появятся здесь после тестов или вызовов опубликованных инструментов за выбранный период.',
'usage.outcomes.title': 'Исходы',
'usage.outcomes.subtitle': 'Группировка по безопасному исходу выполнения.',
'usage.outcomes.empty.title': 'Разбивки по исходам пока нет',
'usage.outcomes.empty.sub': 'Группы исходов появятся после записи вызовов.',
'usage.outcomes.p50': 'p50',
'usage.outcomes.p95': 'p95',
'usage.outcomes.p99': 'p99',
'usage.outcome.success': 'Успех',
'usage.outcome.upstream': 'Upstream',
'usage.outcome.client': 'Клиент',
'usage.outcome.schema': 'Схема',
'usage.outcome.crank': 'Crank',
'usage.outcome.no_error_code': 'Без error code',
'usage.table.title': 'По операциям',
'usage.table.subtitle': 'Разбивка за период: {period}',
'usage.table.th.operation': 'Операция',
@@ -1241,7 +1485,9 @@ var TRANSLATIONS = {
'usage.export.empty.title': 'Данные по использованию не загружены',
'usage.export.empty.body': 'Сначала загрузите данные использования, а потом экспортируйте снимок CSV.',
'usage.export.done.title': 'Использование экспортировано',
'usage.export.done.body': 'Текущий снимок использования экспортирован в CSV.',
'usage.export.done.body': 'Отфильтрованный набор использования экспортирован в CSV.',
'usage.export.error.title': 'Не удалось экспортировать',
'usage.export.error.body': 'Не удалось экспортировать данные использования.',
'usage.chart.ok': 'Успешных: {count}',
'usage.chart.errors': 'Ошибок: {count}',
'usage.chart.week': 'Нед. {index}',
@@ -1295,6 +1541,7 @@ var TRANSLATIONS = {
'settings.security.change_password': 'Сменить пароль',
'settings.security.mismatch': 'Новый пароль и подтверждение не совпадают.',
'settings.security.saved': 'Пароль обновлен.',
'settings.security.saved_relogin': 'Пароль обновлен. Войдите снова.',
'settings.security.save_error': 'Не удалось изменить пароль',
'settings.capability.rest': 'REST / HTTP',
'settings.capability.standard': 'standard',
@@ -1619,6 +1866,7 @@ var TRANSLATIONS = {
'wizard.quality.blocked_title': 'Проверка нашла блокирующие ошибки',
'wizard.quality.blocked_body': 'Исправьте замечания уровня «Ошибка» перед публикацией.',
'wizard.quality.blocking_error': 'Исправьте блокирующие замечания качества перед публикацией.',
'wizard.quality.import_findings_hint': 'Эти замечания получены при импорте OpenAPI. Запустите проверку качества, чтобы пересчитать их для текущего черновика.',
'wizard.quality.severity_error': 'Ошибка',
'wizard.quality.severity_warning': 'Предупреждение',
'wizard.quality.severity_info': 'Информация',
@@ -1635,6 +1883,16 @@ var TRANSLATIONS = {
'wizard.yaml.loaded_body': 'YAML-конфигурация загружена.',
'wizard.publish.done': 'Операция опубликована',
'wizard.publish.done_body': 'Версия {version} опубликована и теперь может быть привязана к агентам.',
'wizard.publish.confirm': 'Опубликовать сохранённый черновик как новую неизменяемую версию?',
'wizard.stale.title': 'Черновик изменён в другом окне',
'wizard.stale.body': 'Ваши правки сохранены в этом браузере. Перезагрузите последнюю сохранённую версию перед повторной попыткой.',
'wizard.test.correlation': 'Request ID: {requestId}\nTrace ID: {traceId}',
'wizard.test.request_id': 'Request ID',
'wizard.test.trace_id': 'Trace ID',
'wizard.test.copy_request_id': 'Копировать Request ID',
'wizard.test.copy_trace_id': 'Копировать Trace ID',
'wizard.test.id_copied': 'Идентификатор поддержки скопирован',
'wizard.test.id_copied_body': 'Идентификатор скопирован без содержимого запроса или ответа.',
// Common buttons
'btn.save': 'Сохранить',
@@ -1677,6 +1935,7 @@ var TRANSLATIONS = {
'agents.card.keys': 'ключей',
'agents.card.calls_today': 'вызовов сегодня',
'agents.card.created': 'Создан {date}',
'agents.card.revision': 'Черновик v{draft} · Опубликована v{published} · Ревизия каталога {revision}',
'agents.card.copy_endpoint': 'Скопировать endpoint',
'agents.card.endpoint_help': 'Данный эндпоинт требуется указать на стороне MCP клиента вместе с API ключом.',
'agents.card.endpoint_help_community': 'Данный эндпоинт требуется указать на стороне MCP клиента вместе с API ключом.',
@@ -1701,6 +1960,7 @@ var TRANSLATIONS = {
'agents.drawer.optional': '(необязательно)',
'agents.drawer.required': 'обязательно',
'agents.drawer.status': 'Статус',
'agents.drawer.revision': 'Черновик v{draft} · Опубликована v{published} · Ревизия каталога {revision}',
'agents.drawer.endpoint': 'MCP endpoint',
'agents.drawer.slug_hint': 'Slug используется как часть endpoint-а для идентификации агента.',
'agents.drawer.placeholder.name': 'Customer Support',
@@ -1759,12 +2019,17 @@ var TRANSLATIONS = {
'agents.toast.delete_message': 'Агент {name} удален.',
'agents.toast.delete_error_title': 'Не удалось удалить',
'agents.toast.delete_error_message': 'Не удалось удалить агента',
'agents.toast.delete_forbidden_message': 'Опубликованных агентов нельзя удалить. Сначала архивируйте или снимите агента с публикации.',
'agents.toast.lifecycle_title': 'Жизненный цикл агента обновлен',
'agents.toast.lifecycle_publish_confirm': 'Опубликовать {name}? Опубликованный MCP-каталог изменится.',
'agents.toast.lifecycle_unpublish_confirm': 'Снять {name} с публикации? Текущие MCP-клиенты больше не увидят этот каталог агента.',
'agents.toast.lifecycle_archive_confirm': 'Архивировать {name}? Новые публикации и привязки будут заблокированы.',
'agents.toast.lifecycle_publish': '{name} опубликован.',
'agents.toast.lifecycle_unpublish': '{name} возвращен в черновик.',
'agents.toast.lifecycle_archive': '{name} архивирован.',
'agents.toast.lifecycle_error_title': 'Не удалось обновить жизненный цикл',
'agents.toast.lifecycle_error_message': 'Не удалось обновить состояние агента',
'agents.toast.stale_message': 'Агент изменился в другом запросе. Перезагрузите форму и повторите действие.',
'agents.toast.endpoint_title': 'MCP endpoint скопирован',
// Demo content
@@ -1781,9 +2046,24 @@ var TRANSLATIONS = {
'login.email_label': 'Email адрес',
'login.email_placeholder': 'you@acme.com',
'login.password_only': 'Войдите с помощью email и пароля.',
'login.bootstrap.title': 'Создать администратора',
'login.bootstrap.subtitle': 'Завершите локальную первичную настройку',
'login.bootstrap.note': 'Введите одноразовый токен из crank-migrate и задайте первый пароль администратора.',
'login.bootstrap.token_label': 'Bootstrap token',
'login.bootstrap.token_placeholder': 'Вставьте одноразовый bootstrap token',
'login.bootstrap.submit': 'Создать администратора',
'login.loading': 'Входим…',
'login.success': 'Вход выполнен. Перенаправляем…',
'login.bootstrap.loading': 'Создаем администратора…',
'login.bootstrap.success': 'Администратор создан. Перенаправляем…',
'login.error.required': 'Введите email и пароль.',
'login.bootstrap.error.required': 'Введите bootstrap token и пароль.',
'login.error.invalid': 'Неверный email или пароль. Попробуйте еще раз.',
'login.error.throttled': 'Слишком много попыток. Подождите и попробуйте снова.',
'login.error.expired_session': 'Сессия истекла. Войдите снова.',
'login.error.generic': 'Сейчас не удается войти. Попробуйте еще раз.',
'login.error.request_id': 'Request ID',
'login.error.trace_id': 'Trace ID',
}
};
@@ -1793,6 +2073,36 @@ Object.assign(TRANSLATIONS.en, {
});
Object.assign(TRANSLATIONS.ru, {
'execution.error.authorization_denied': 'Выполнение операции запрещено.',
'execution.error.auth_profile_not_found': 'Профиль авторизации не найден.',
'execution.error.secret_not_found': 'Секрет авторизации не найден.',
'execution.error.secret_invalid': 'Секрет авторизации имеет неподходящий формат.',
'execution.error.input_schema_invalid': 'Входные параметры не прошли проверку схемы.',
'execution.error.input_mapping_invalid': 'Не удалось сопоставить входные параметры.',
'execution.error.prepared_request_invalid': 'Не удалось подготовить корректный API-запрос.',
'execution.error.execution_overloaded': 'Сервис временно перегружен.',
'execution.error.safety_store_unavailable': 'Обязательное хранилище безопасности недоступно.',
'execution.error.protocol_unsupported': 'Протокол операции не поддерживается.',
'execution.error.execution_mode_unsupported': 'Режим выполнения не поддерживается.',
'execution.error.adapter_configuration_invalid': 'Конфигурация адаптера некорректна.',
'execution.error.outbound_target_rejected': 'Целевой адрес отклонён политикой безопасности.',
'execution.error.upstream_auth_error': 'Внешний API отклонил авторизацию.',
'execution.error.upstream_not_found': 'Ресурс внешнего API не найден.',
'execution.error.upstream_rate_limited': 'Внешний API ограничил частоту запросов.',
'execution.error.upstream_server_error': 'Внешний API временно недоступен.',
'execution.error.upstream_status_error': 'Внешний API вернул ошибочный статус.',
'execution.error.upstream_timeout': 'Истекло время ожидания внешнего API.',
'execution.error.upstream_transport_error': 'Не удалось подключиться к внешнему API.',
'execution.error.upstream_response_too_large': 'Ответ внешнего API превышает лимит.',
'execution.error.output_mapping_invalid': 'Не удалось сопоставить ответ внешнего API.',
'execution.error.output_schema_invalid': 'Ответ не прошёл проверку схемы.',
'execution.error.persistence_unavailable': 'Обязательное сохранение результата недоступно.',
'execution.error.runtime_internal': 'Внутренняя ошибка выполнения.',
'execution.error.confirmation_required': 'Операция требует подтверждения.',
'execution.error.confirmation_invalid': 'Подтверждение недействительно или истекло.',
'execution.error.idempotency_in_progress': 'Операция с этим ключом уже выполняется.',
'execution.error.idempotency_conflict': 'Ключ идемпотентности использован с другими параметрами.',
'execution.error.idempotency_outcome_unknown': 'Результат предыдущего выполнения неизвестен; автоматический повтор запрещён.',
});