# Cebian 扩展 i18n —— 简体中文（zh_CN，大陆用户）。
# 修改时请同步 locales/en.yml 与 locales/zh_TW.yml。规范见 .agents/skills/i18n-naming/SKILL.md。

# ─── Manifest（扁平顶层 key，见规范"Manifest localization"）───
extName: "Cebian · 开源 AI 侧边栏智能体 · 自备 API Key"
extDescription: "浏览器侧边栏里的 AI 智能体，用你自己的 OpenAI / Anthropic / Google API Key，免订阅、无账号。读网页、拾取元素、装 MCP 工具、跑 Skill 工作流，数据全部本地存储。AGPL-3.0 开源。"
actionTitle: "打开 Cebian 侧边栏"

# ─── 通用（UI 中复用）───
common:
  newChat: "新对话"
  send: "发送"
  history: "历史记录"
  toggleTheme: "切换主题"
  settings: "设置"
  back: "返回"
  openInNewTab: "在新标签页打开"
  loading: "加载中…"
  cancel: "取消"
  confirm: "确认"
  save: "保存"
  delete: "删除"
  rename: "重命名"
  edit: "编辑"
  add: "添加"
  code: "代码"
  copy: "复制"
  copied: "已复制"
  copyFailed: "复制失败"
  download: "下载"
  downloadFailed: "下载失败"
  newFile: "新建文件"
  newFolder: "新建文件夹"
  search: "搜索"
  searchPlaceholder: "搜索…"
  moreActions: "更多操作"
  empty:
    history: "暂无历史记录"
    folder: "空文件夹"
  time:
    justNow: "刚刚"
    # $1 = 分钟数
    minutesAgo: "$1 分钟前"
    # $1 = 小时数
    hoursAgo: "$1 小时前"
    # $1 = 天数
    daysAgo: "$1 天前"
    # $1 = 月数
    monthsAgo: "$1 个月前"
    # $1 = 年数
    yearsAgo: "$1 年前"
  session:
    deleteConfirmTitle: "删除会话？"
    # $1 = 会话标题
    deleteConfirmDescription: "“$1”以及它的工作区文件将被永久删除，此操作不可撤销。"
    running: "工作中"
    # $1 = 消息数
    messageCount:
      0: "暂无消息"
      1: "1 条消息"
      n: "$1 条消息"

# ─── 设置 ───
settings:
  nav:
    aria: "设置导航"
    providers: "提供商"
    instructions: "指引"
    prompts: "提示词"
    skills: "技能"
    mcp: "MCP 服务器"
    advanced: "高级"
    about: "关于"
  providers:
    title: "AI 提供商"
  about:
    title: "关于"
    tagline: "AI 浏览器侧边栏助手"
    feedback: "反馈"
    checkUpdate: "检查更新"
    checking: "检查中…"
    upToDate: "已是最新版本"
    # $1 = new version string (e.g. "1.2.3")
    updateAvailable: "发现新版本 v$1"
    viewInstallGuide: "查看安装指南"
    checkFailed: "检查更新失败"
    followAuthor: "关注作者"
    socials:
      wechat: "微信公众号"
      wechatHandle: "一只猫头猫"
      bilibili: "哔哩哔哩"
      bilibiliHandle: "不想睡觉猫头猫"
      xiaohongshu: "小红书"
      xiaohongshuHandle: "一只猫头猫"
      x: "X"
      xHandle: "@maotoumao0_0"
  advanced:
    title: "高级"
    maxRounds:
      label: "最大对话轮数"
      hint: "超出后自动截断早期消息"
  instructions:
    title: "指引"
    label: "自定义指引"
    hint: "追加到默认规则之后，用于调整回复语言、风格或角色。无法覆盖工具协议和安全规则。"
    placeholder: "例如：\n- 用中文回复\n- 回答尽量简洁\n- 讨论代码时默认使用 TypeScript"
  prompts:
    title: "提示词"
    newBody: "（在此处编写你的提示词）"
    # $1 = 触发字符（“/”）
    hint: "可复用的提示模板，通过 $1 命令在聊天输入中触发。"
    placeholders:
      selectedText: "页面选中文本"
      pageUrl: "当前页面 URL"
      pageTitle: "当前页面标题"
      date: "当前日期"
      clipboard: "剪贴板内容"
  skills:
    title: "技能"
    newBody: "（在此处编写技能指令）"
    create: "创建技能"
    hint: "遵循 agentskills.io 规范的多文件技能包，agent 会按需加载。"
    import: "导入…"
    exportCurrent: "导出"
    exportAll: "导出全部"
    exportEmpty: "没有可导出的技能"
    # $1 = 技能名称
    exportSuccess: "已导出 “$1”"
    # $1 = 导出技能数量
    exportAllSuccess:
      1: "已导出 1 个技能"
      n: "已导出 $1 个技能"
    # $1 = 导入的技能名称
    importSuccess: "已导入 “$1”"
    # $1 = 导入技能数量
    importSuccessBackup:
      1: "已导入 1 个技能"
      n: "已导入 $1 个技能"
    importDialog:
      titleSingle: "导入技能"
      titleBackup: "导入技能备份"
      permissionsHeading: "申请的权限"
      permissionsNone: "未申请特殊权限。"
      hasScriptsWarning: "包含 scripts/ 下的可执行脚本。"
      # $1 = 文件数
      fileCount:
        1: "1 个文件"
        n: "$1 个文件"
      # $1 = 技能数
      skillCount:
        1: "1 个技能"
        n: "$1 个技能"
      # $1 = 已存在的源名称, $2 = 重命名后的目标名称
      conflictNotice: "已存在名为 “$1” 的技能。除非选择覆盖，否则将导入为 “$2”。"
      overwrite: "覆盖现有"
      keepBoth: "保留两者"
      confirmOverwriteTitle: "覆盖现有技能？"
      # $1 = 技能名称（多个时以逗号分隔）
      confirmOverwriteDescription: "“$1” 将被替换，且已授予的权限将被清除。是否继续？"
  mcp:
    title: "MCP 服务器"
    description: "接入 Model Context Protocol 服务器，把它们的工具暴露给 agent 使用。"
    empty:
      title: "尚未配置 MCP 服务器"
      hint: "添加一个服务器，用外部工具扩展 agent 的能力。"
    actions:
      add: "添加 MCP 服务器"
      toggle: "启用服务器"
      edit: "编辑服务器"
      delete: "删除服务器"
      deleteConfirmTitle: "删除 MCP 服务器？"
      # $1 = 服务器名称
      deleteConfirmDescription: "“$1”将被删除，此操作不可撤销。"
    errors:
      # $1 = 服务器名称
      nameTaken: "已存在名为“$1”的 MCP 服务器。"
      nameRequired: "服务器名称不能为空。"
      urlRequired: "服务器 URL 不能为空。"
      # $1 = URL
      urlInvalid: "服务器 URL 无效：$1"
      # $1 = scheme（例如 "ftp:"）
      urlScheme: "不支持的 URL 协议：$1"
      bearerTokenRequired: "Bearer Token 不能为空。"
      authHeaderConflict: "使用 Bearer 认证时请勿手动设置 Authorization header，请在认证字段中填写 token。"
    status:
      disabled: "已禁用"
      idle: "等待首次调用"
      connected: "已连接"
      disconnected: "未连接"
      probing: "重连中"
      circuitOpen: "暂时不可用"
    form:
      name: "名称"
      namePlaceholder: "例如：weather、github、my-tools"
      transport: "传输协议"
      url: "URL"
      urlPlaceholder: "https://example.com/mcp"
      authType: "认证方式"
      authNone: "无"
      authBearer: "Bearer Token"
      bearerToken: "Token"
      bearerTokenPlaceholder: "粘贴 bearer token"
      headers: "自定义 Headers"
      headerKeyPlaceholder: "Header 名（如 X-MCP-Toolsets）"
      headerValuePlaceholder: "Header 值"
      addHeader: "添加 Header"
      removeHeader: "移除 Header"
  editor:
    selectFile: "选择一个文件开始编辑"
    saving: "保存中…"
    saveFailed: "保存失败"
    unsaved: "未保存"
    saved: "已保存"
  files:
    backToList: "返回文件列表"
    selectOrCreate: "从左侧选择或创建文件"

# ─── 聊天 ───
chat:
  composer:
    placeholder: "输入 / 查看命令…"
    pickElement: "选择元素"
    cancelPick: "取消选择"
    screenshot: "截图"
    uploadFile: "上传文件"
    mobileMode: "移动端模式"
    needModel: "请先选择一个 AI 模型"
    goToSettings: "前往设置"
    readPromptFailed: "读取 Prompt 失败"
    elementAdded: "该元素已添加"
    elementPickFailed: "元素选择失败"
    elementPickUnsupported: "当前页面不支持元素选取"
    elementPickNavigated: "页面已跳转，元素选取已取消"
    imageAlreadyAdded: "该图片已添加"
    screenshotFailed: "截图失败"
    # $1 = 附件上限个数
    maxAttachments: "最多添加 $1 个附件"
    # $1 = 实际添加的文件数
    truncatedFiles: "仅添加前 $1 个文件，已达上限"
    # $1 = 文件名，$2 = 体积上限（已格式化，如 “5 MB”）
    fileTooLarge: "$1 超过 $2 限制"
    # $1 = 文件名
    readFileFailed: "读取失败：$1"
    # $1 = 文件名
    unsupportedFileType: "不支持的文件类型：$1"
    noPrompts: "暂无 Prompt，前往 AI 配置创建"
    noMatch: "无匹配结果"
    iframeEnterHint: "⏎ 点击进入"
  attachments:
    image: "图片"
    screenshot: "截图"
    imageAlt: "附件图片"
    # $1 = 事件数量, $2 = 时长 (M:SS)
    recordingMeta: "$1 个事件 · $2"
    recordingTruncated: "已截断"
    recordingDownload: "下载录制 JSON"
    # $1 = 事件数量, $2 = 简短字符数（如 1.2K、3M）
    recordingHover: "$1 个事件 · 约 $2 字符"
  recorder:
    start: "开始录制用户操作"
    stop: "停止录制（会随下一条消息发送）"
    startRejectedBusy: "另一个侧边栏正在录制，请先停止后再开始新的录制。"
    autoStoppedEvents: "录制已自动停止：达到事件上限"
    autoStoppedTime: "录制已自动停止：达到时长上限"
  askUser:
    placeholder: "输入回复…"
  model:
    select: "选择模型"
    searchPlaceholder: "搜索模型…"
    notFound: "未找到模型"
    addMore: "前往设置添加更多提供商"
  thinking:
    # $1 = 当前等级 label
    label: "思考：$1"
    levels:
      "off": "关闭"
      minimal: "最小"
      low: "低"
      medium: "中"
      high: "高"
  tool:
    args: "参数"
    result: "结果"
  mcpApp:
    # MCP App HTML 拉取中显示
    loading: "加载交互视图中…"
    # 拉取失败时重试按钮文案
    retry: "重试"
    # 后台没给具体 message 时的兜底文案
    errorGeneric: "加载交互视图失败"
    # 按错误码分发的文案。BG 原始 message 会作为详情拼在后面
    errorServerUnavailable: "该 MCP server 已不可用，请到设置里重新启用该服务。"
    # $1 = 后台的原始错误描述
    errorFetchFailed: "加载交互视图失败：$1"
  message:
    # $1 = 输入 token 数（已格式化，如 "1.2k"），$2 = 输出 token 数（已格式化）
    tokensInOut: "↑$1 ↓$2"
    # 缓存明细（无写入）。$1 = 未缓存、$2 = 缓存命中（均已格式化）
    tokensInBreakdownHit: "未缓存 $1 · 缓存 $2"
    # 缓存明细（含写入）。$1 = 未缓存、$2 = 缓存命中、$3 = 写入缓存（均已格式化）
    tokensInBreakdownHitWrite: "未缓存 $1 · 缓存 $2 · 写缓存 $3"
    # 最新一轮 assistant 消息左下角重试按钮的 tooltip / aria-label
    retry: "重试"
  session:
    loading: "加载会话中…"
    modelError: "模型返回错误"
    # 用户中途点停后，在 assistant 气泡里显示的提示。
    # 保持中性语气——不是错误，只是没跑完。
    cancelled: "已取消"
    # 后台端口还没连上时（通常发生在 SW 刚唤醒 / 断开重连期间）点发送/重试会看到这条
    notConnected: "未连接到后台服务，请稍后再试"
    # 自动重连多次失败后提示。语气是「还在试」，不保证能连上
    reconnecting: "连接断开，正在重试…"
    welcomeReady: "有什么我可以帮你的？"
    scrollToBottom: "跳至最新消息"

# ─── 提供商子组件（OAuth / API Key / 自定义）───
provider:
  section:
    viaApiKey: "通过 API Key"
  status:
    connected: "已连接"
    notConfigured: "未配置"
    unverified: "未验证"
    verifying: "验证中"
    connectFailed: "连接失败"
    failed: "失败"
  oauth:
    signIn: "登录"
    signOut: "退出"
    loggedIn: "已登录"
    notLoggedIn: "未登录"
    authorizing: "授权中"
    authFailed: "授权失败"
    enterCode: "请在浏览器中输入代码："
    completeInBrowser: "请在弹出的浏览器窗口中完成授权…"
    descriptions:
      githubCopilot: "使用 Copilot 订阅访问 GPT/Claude"
      openaiCodex: "使用 ChatGPT Plus/Pro 订阅"
  apiKey:
    placeholder: "输入 API Key"
    disconnect: "断开连接"
    noModels: "无可用模型"
    verifyNoResponse: "验证失败：未收到预期响应"
    # $1 = 模型数量
    connectedWithCount: "已连接 · $1 个模型"
  summary:
    # $1 = 认证方式（OAuth / API Key），$2 = 模型数量
    modelsAvailable: "$1 · $2 个模型可用"
  form:
    name: "名称"
    namePlaceholder: "例如：My Ollama"
    baseUrl: "Base URL"
    baseUrlPlaceholder: "例如：http://localhost:11434/v1"
    apiKeyOptional: "API Key（可选）"
    apiKeyPlaceholder: "留空则不传认证"
    models: "模型列表"
    autoFetch: "自动获取"
    reasoning: "推理"
    manualModelPlaceholder: "手动输入 Model ID"
    addCustom: "添加自定义提供商"
    fetchFailed: "无法获取模型列表，请手动添加"

# ─── 工具运行时标签（在 ToolCard 中显示）───
tools:
  # $1 = mode（及可选 selector 后缀）
  readPage: "正在阅读页面内容 ($1)"
  executeJs: "正在执行脚本"
  screenshot: "正在截取页面截图"
  askUser: "等待用户回答"
  # $1 = 技能名称
  runSkill: "正在执行技能脚本 $1"
  # $1 = MCP 服务器 slug（展示形式），$2 = 远端工具名
  mcpCall: "$1 · $2"
  fs:
    # $1 = 文件路径
    createFile: "正在创建文件 $1"
    # $1 = 文件路径
    editFile: "正在编辑文件 $1"
    # $1 = 目录路径
    mkdir: "正在创建目录 $1"
    # $1 = 原路径
    rename: "正在重命名 $1"
    # $1 = 路径
    delete: "正在删除 $1"
    # $1 = 文件路径
    readFile: "正在读取文件 $1"
    # $1 = 目录路径
    list: "正在列出目录 $1"
    # $1 = 搜索模式
    searchFiles: "正在搜索文件 \"$1\""
    # $1 = 搜索模式
    searchContent: "正在搜索文件内容 \"$1\""
    # $1 = 目标路径
    saveUrl: "正在保存 URL 到 $1"
  chromeApi:
    help: "正在查询 Chrome API 文档"
    # $1 = namespace，$2 = method
    call: "正在调用 chrome.$1.$2"
  interact:
    # $1 = 目标后缀（含前导空格）或为空
    click: "正在点击$1"
    dblclick: "正在双击$1"
    rightclick: "正在右键点击$1"
    hover: "正在悬浮$1"
    focus: "正在聚焦$1"
    type: "正在输入文本$1"
    clear: "正在清除输入框$1"
    select: "正在选择选项$1"
    scroll: "正在滚动页面"
    # $1 = 按键名
    keypress: "正在按键 $1"
    # $1 = 目标后缀（含前导空格）或为空
    wait: "正在等待元素出现$1"
    waitHidden: "正在等待元素消失$1"
    waitNavigation: "正在等待页面加载"
    # $1 = 步骤数
    sequence: "正在执行操作序列 ($1 步)"
    # $1 = action 名称
    unknown: "interact: $1"
  inspect:
    # $1 = selector
    selector: "正在检查 $1"
    # $1 = 搜索文本
    text: "正在按文本检查 \"$1\""
    page: "正在检查页面"
  tab:
    open: "正在打开新标签页"
    # $1 = 标签页 id
    close: "正在关闭标签页 $1"
    # $1 = 标签页 id
    switch: "正在切换标签页 $1"
    reload: "正在刷新页面"
    listFrames: "正在列出页面 frames"
    # $1 = action 名称
    unknown: "tab: $1"

# ─── 对话框 ───
dialogs:
  imagePreview:
    title: "图片预览"
    alt: "预览"

# ─── VFS 浏览入口 ───
vfs:

  backToRoot: "返回根目录"
  zipping: "打包中…"
  # $1 = 行数
  lines: "$1 行"
  # $1 = 格式化后的文件大小
  binaryFile: "[二进制文件 — $1]"
  # $1 = 格式化后的文件大小
  tooLargeToPreview: "文件太大，无法预览（$1）。请改用下载。"
  preview: "预览"
  viewSource: "查看源码"
  # $1 = 路径
  pathNotFound: "路径不存在：$1"
  unknownError: "未知错误"

# ─── 错误（toast、抛出的错误信息）───
errors:
  oauth:
    cancelled: "已取消"
    timeout: "授权超时"
    noCode: "未收到授权码"
    stateMismatch: "State 不匹配"
    # $1 = HTTP 状态码
    tokenExchangeFailed: "Token 交换失败：$1"
    missingTokenFields: "Token 响应缺少必要字段"
    missingRefreshToken: "未收到 refresh token"
    missingRefreshTokenLocal: "缺少 refresh token"
    # $1 = provider id
    unknownProvider: "未知的 OAuth provider：$1"
  network:
    invalidUrl: "URL 格式无效"
    unsupportedScheme: "仅支持 http/https 协议"
    # $1 = HTTP 状态码
    requestFailed: "请求失败：$1"
  mobile:
    toggleFailed: "移动端模式切换失败"
  skillPackage:
    invalid: "无效的技能包。"
    tooLarge: "技能包过大。"
    tooManyFiles: "技能包包含过多文件。"
    missingEntry: "技能包缺少 SKILL.md。"
    # $1 = 路径
    unsafePath: "技能包中存在不安全的路径：$1"
    # $1 = 权限名称
    unsupportedPermission: "申请了不支持的权限：$1"
    # $1 = 技能名称
    invalidName: "无效的技能名称：$1"
    # $1 = 技能名称
    reservedName: "该技能名称为系统保留：$1"
    parseFrontmatter: "无法解析 SKILL.md 的 frontmatter。"
