跳到内容
Sonenta

CLI

v0.2.1 · npm · MIT

@sonenta/cli

一个轻量、可脚本化的命令行,用于完成你原本会在 dashboard 中点击操作的一切:导入已有的 i18next 项目、推送和拉取翻译、将 CI 与远端做差异比对、发布 CDN release,以及为 offline-first 构建快照打包。MIT 许可,发布在 npm 上。

破坏性变更 · 0.1 → 0.2

整个 CLI 现在都通过 MCP surface 运行:它需要一个 mcp:* scope 的 API key——限定到项目的 key 会返回 403。在 dashboard 的 Org Settings → API Keys 下生成一个,并重新签发任何曾在 0.1 中使用的 key。

安装

仅支持 npm——CLI 没有 Homebrew formula。需要 Node 18 或更新版本,安装后会提供 sonenta 命令。

terminal
1# 全局安装一次2npm i -g @sonenta/cli 4# 或无需安装直接运行5npx @sonenta/cli <command>

身份认证

每次调用都会以 mcp:* scope 发送 Authorization: ApiKey <prefix>.<secret>。登录一次即可将 key 存入 ~/.sonenta/credentials,或在 CI 中设置 SONENTA_TOKEN

terminal
1# 交互式——按 host 将 key 存入 ~/.sonenta/credentials(0600)2sonenta login --host https://api.sonenta.com3API key: snt_live_••••••••.••••••••••••••••4✓ 已为 https://api.sonenta.com 保存 6# CI——无提示,从环境中读取 key7export SONENTA_TOKEN=snt_live_<prefix>.<secret>8sonenta push

解析顺序,先匹配者优先:SONENTA_TOKEN 环境变量,然后是当前活动 host 对应的 ~/.sonenta/credentials。在 Org Settings → API Keys 下以 mcp:* scope 生成该 key。

配置

sonenta init 会在你的仓库中写入一个 sonenta.config.json(通过从当前工作目录向上查找来解析)。凭据单独存放、按用户保存,且永远不会被提交。

sonenta.config.json
1# 提交到你的仓库——此处不含任何 secret2{3  "host": "https://api.sonenta.com",4  "project_uuid": "<project_uuid>",5  "version_slug": "main"6}
~/.sonenta/credentials
1# ~/.sonenta/credentials——0600 权限,按用户保存,切勿提交2{ "default": "https://api.sonenta.com",3  "hosts": {4    "https://api.sonenta.com": { "api_key": "snt_live_..." }5  } }

version_slug 默认为 main。请勿将 API key 放入 sonenta.config.json——它只应存在于凭据文件或 SONENTA_TOKEN 中。

命令

按用途分组——设置认证与配置、检视项目,或同步翻译。每个命令都通过 MCP surface 运行,并遵循 sonenta.config.json

认证与配置

sonenta login 为某个 host 存储一个 API key。

选项

  • --host <url> 要进行认证的 API host。
  • --token <key> 以非交互方式传入 key,而非通过提示输入。

示例

sonenta login --host https://api.sonenta.com
sonenta logout 移除某个 host 已存储的凭据。

选项

无选项。

示例

sonenta logout
sonenta whoami 显示当前活动 host 和一个掩码后的 key。

选项

无选项。

示例

sonenta whoami
sonenta init 为某个项目脚手架生成 sonenta.config.json。

选项

  • --project <uuid> 要写入配置的项目 UUID(必填)。
  • --version <slug> 要瞄准的版本 slug(默认 main)。
  • --force 覆盖已存在的配置文件。

示例

sonenta init --project <uuid> --version main

检视

sonenta projects list 列出你的 key 可访问的项目。

选项

无选项。

示例

sonenta projects list
sonenta keys list 以 namespace_slug/key_name 形式列出 key。

选项

  • --namespace <slug> 限定到某个 namespace。

示例

sonenta keys list --namespace common
sonenta status 将你本地的 locales/ 与远端做差异比对。

选项

  • --language <code> 将差异比对限定到某一种语言。
  • --namespace <slug> 将差异比对限定到某个 namespace。
  • --src <dir> 源目录(默认 locales)。

示例

sonenta status
sonenta missing 列出运行时检测到的缺失 key。

选项

  • --language <code> 按语言过滤。
  • --namespace <slug> 按 namespace 过滤。
  • --limit <n> 限制行数上限。

示例

sonenta missing --limit 50

导入与同步

sonenta import <files...> 一次性 i18next 导入——嵌套或扁平均可;创建 key、upsert 翻译、幂等。

选项

  • --dry-run 仅预览;不发送任何内容。
  • --status <draft|translated> 传入状态(默认 translated)。
  • --language <code> 强制指定语言,而非从路径推断。
  • --namespace <slug> 强制指定 namespace(对于裸的 <lang>.json 为必填)。
  • --version <slug> 瞄准一个非默认版本。

示例

sonenta import locales/fr/common.json
sonenta push 在单次 import 调用中推送整个本地 locales/ 树。

选项

  • --src <dir> 源目录(默认 locales)。
  • --dry-run 仅预览;不发送任何内容。
  • --status <state> 传入状态(默认 translated)。

示例

sonenta push --dry-run
sonenta pull 将远端翻译写入 locales/<lang>/<namespace>.json(扁平)。

选项

  • --language <code> 限定到某一种语言。
  • --namespace <slug> 限定到某个 namespace。
  • --dest <dir> 目标目录(默认 locales)。

示例

sonenta pull --language fr
sonenta export 导出为 i18next JSON——默认扁平,使用 --nested 输出树形结构。

选项

  • --nested 输出嵌套树形结构,而非扁平 key。
  • --out <dir> 将文件写入某个目录,而非 stdout。

示例

sonenta export --nested --out ./dump
sonenta releases publish 触发一次 CDN release;已订阅的 SDK 会实时刷新。

选项

  • --version <slug> 要发布的版本(默认 main)。
  • --dry-run 仅预览;不发布任何内容。

示例

sonenta releases publish
sonenta snapshot 将公开的 CDN bundle 抓取到一个构建期模块中,用于 SDK 的 offline-first 回退。

选项

  • --format <ts|json> 输出格式:ts(默认)或 json。
  • --out <file> 写入文件,而非 stdout。
  • --cdn <base> CDN 基址(默认 https://cdn.sonenta.com)。

示例

sonenta snapshot --out src/sonenta-bundles.ts

每个命令也都接受 --host <url>,可在单次运行中覆盖已配置的 API host。

0.1 → 0.2 破坏性变更

正在从 0.1 升级?有两处变更需要你采取行动。

下一步