---
title: 规范
description: 代码命名规范、i18n 翻译术语表、中文风格指南的唯一权威来源。
---

本页是代码命名规范、i18n 翻译术语表、中文风格指南的唯一权威来源。原本散落在 `packages/views/locales/glossary.md` 和各处注释里的规则现在都收拢到这里。

写 Multica 代码、改翻译、写中文产品文案，都从这一页查。

---

## 1. 代码命名

### 路由

工作区前置路由（用户进入工作区之前能访问的路由）必须用单个单词，或者 `/{noun}/{verb}` 格式。

- ✅ `/login`、`/inbox`、`/workspaces/new`
- ❌ `/new-workspace`、`/create-team`、`/accept-invite`

根目录的连字符词组会跟用户自选 workspace slug 冲突，逼着团队不停审保留字列表。把名词（`workspaces`）保留下来，整个 `/workspaces/*` 子树自动受保护。

### 工作区路由

永远用 `/{slug}/{section}` —— `/{slug}/issues`、`/{slug}/agents`、`/{slug}/settings`。共享代码不要复制路由逻辑，统一走 `useNavigation().push()`，不要直接用框架的 link API。

### 包与模块

monorepo 的包边界是硬约束：

| 包 | 可依赖 | 不能依赖 |
| --- | --- | --- |
| `packages/core` | 仅平台无关基础库 | `react-dom`、`localStorage`、`process.env`、`next/*`、UI 库 |
| `packages/ui` | 无业务依赖 | `@multica/core`、业务逻辑 |
| `packages/views` | `core/`、`ui/` | `next/*`、`react-router-dom`、stores |
| `apps/web/platform/` | `next/*` | 其他 app |
| `apps/desktop/.../platform/` | `react-router-dom`、electron | 其他 app |

两个 app 都有的逻辑，**必须**抽到共享包。"小段重复"也不算例外。

### 文件与组件

- 文件名：`kebab-case.tsx` / `kebab-case.ts`（如 `agent-row-actions.tsx`）
- 组件：`PascalCase`（如 `AgentRowActions`）
- Hook：`useCamelCase`（如 `useWorkspaceId`）
- 测试：与源文件同目录，命名 `<file>.test.ts(x)`
- Zustand store：`<feature>-store.ts`，导出名 `use<Feature>Store`

### 数据库（Go + sqlc）

- 表名：`snake_case` 单数（`user`、`workspace`、`agent_runtime`）
- 字段：`snake_case`（`workspace_id`、`created_at`、`last_seen_at`）
- 外键：`<table>_id`
- 布尔：`is_<state>` 或者 `<state>_at`（状态变化优先用时间戳形式）
- 迁移文件：`NNN_descriptive_name.up.sql` + `.down.sql`，**永远写双向**

### Go

- 标准 `gofmt` + `go vet`，无例外
- Handler 文件按域命名：`agent.go`、`auth.go`、`runtime.go`
- 测试：`<file>_test.go` 同目录
- handler 里 UUID 解析遵守根 `CLAUDE.md` 的规则：边界输入用 `parseUUIDOrBadRequest`，可信回环用 `parseUUID`（panic 版），永远不要直接用 `util.ParseUUID` 不查 error

### TypeScript

- 网络上 API 响应是 `snake_case`，api client 在边界处转成 `camelCase`。**TS 代码内部一律 camelCase**
- 类型：`PascalCase`（`Issue`、`AgentRuntime`），不加 `IPrefix`，不加 `_t` 后缀
- 枚举：优先用 string literal union，需要 runtime 迭代时才用 `enum`
- TanStack Query key：用 `<feature>/queries.ts` 里的工厂函数，例如 `issueKeys.detail(id)`

### Issue 编号

每个 issue 有人类可读的编号，比如 `MUL-123`：工作区 `issue_prefix`（大写字母和数字，通常 3 个字符，最长 10 个）+ 流水号。工作区管理员可以在 Settings → General 中修改前缀；修改会让所有现有 issue 重新编号，外部引用——PR 标题、分支名、文档与聊天里的链接——里的旧前缀会失效。

### 代码注释

**只允许英文**。Go 和 TypeScript 都强制。如果在代码里看到中文注释，那就是 bug，替换掉。

### Commit message

Conventional 格式：`feat(scope)`、`fix(scope)`、`refactor(scope)`、`docs`、`test(scope)`、`chore(scope)`。按意图原子化分组。

---

## 2. i18n 翻译术语表

这是每个翻译 PR 都必须遵守的术语表。原本在 `packages/views/locales/glossary.md`，那个文件现在是个 stub，指向这一页。

### 核心区分：实体 vs 概念

Multica 的产品名词分两类：

- **实体（typed entity）** —— 有 URL、有数据库 row、是 API 响应里某种 type 的东西。中文里**用小写英文**呈现，视觉上像类型名，告诉读者"这是 Multica 系统里的特定实体"。
- **概念（concept）** —— 不是数据库实体的普通名词。**完整翻译成中文**，CN 用户看不到生硬的英文。

这套规则与 `apps/docs/content/docs/*.zh.mdx` 完全对齐 —— docs 是已经实战 20+ 篇的 CN voice 标准。

### 实体词的混合规则（`issue` / `skill` / `task`）

`issue` / `skill` / `task` 是 Multica 的核心实体。schema 字段、API 字段、产品 UI 标签都用英文。中文里采用**混合规则** —— 词出现在哪里决定怎么写：

| 场景 | 写法 | 例 |
| --- | --- | --- |
| **UI 短句 / 状态名 / 代码上下文** | 小写英文 | "排队中的 task"、"创建子 issue"、"为智能体注入 skill" |
| **doc 标题 / 章节标题** | 首字母大写英文，**或**对应中文术语 | "Issue 与 project"、"Skills"、"执行任务" |
| **doc 正文长篇讨论中作为主语** | 中文术语，首次出现配括号英文 | "**执行任务**（task）是智能体每一次工作的单位" |
| **API / DB 字段** | 永远 `task` / `issue` / `skill` | `task_id`、`issue_status`、`skill_uuid` |

中文术语对照：

- `task` ↔ `执行任务`（上下文清楚后可简写为「任务」）
- `issue` 没有公认中文译法 —— 保留英文；标题可大写为 `Issue`
- `skill` 没有公认中文译法 —— 保留英文；标题可大写为 `Skills`

**为什么 `issue` / `skill` / `task` 不强制译，而 `project` / `autopilot` 必译**：

- **`issue` / `task`**：dev 团队习惯说英文，"任务"在中文里和"工作"几乎同义太空泛，"工单"是 IT 工单语义，"议题"是 GitHub 风格但用户场景不匹配 —— 三个候选都不如 `issue` 准确。**但**在长篇 doc 正文里，重复 50 次 `task` 节奏不顺，所以正文允许用 `执行任务`，UI 短句、状态名仍保持小写英文。
- **`skill`**：Multica 特有概念，没有公认中文译法。
- **`project` 翻成「项目」**：中文里早就稳定的日常词。飞书 / Tower / Teambition / PingCode / GitHub Projects 中文版 0 例外都翻译成「项目」，没有产品保留 `project`。
- **`autopilot` 翻成「自动化」**：autopilot 在中文里联想到特斯拉的「自动驾驶」，跟产品功能（按周期跑 task）对应不上。Notion / 飞书都用「自动化」，是行业共识。

### 完整翻译 —— 概念词

| 英 | 中 |
| --- | --- |
| Workspace | **工作区** |
| Agent | **智能体** |
| Project | **项目** |
| Autopilot | **自动化** |
| Daemon | **守护进程** |
| Runtime | **运行时** |
| Inbox | **收件箱** |
| Comment | **评论** |
| Reply | **回复** |
| Notifications | **通知** |
| Member | **成员** |
| Label | **标签** |
| Settings | **设置** |
| Onboarding | **上手引导** |

### 不翻 —— 品牌名 + 通用缩写

| 类别 | 词 |
| --- | --- |
| 品牌 | **Multica**、GitHub、Slack、Google、Anthropic、OpenAI、Claude、Codex、Cursor、Linear、Jira |
| 缩写 | API、CLI、URL、SDK、OAuth、JWT、SSO、WebSocket、HTTP、JSON、YAML、SQL |

### 完整翻译 —— 通用 UI 词

| 英 | 中 |
| --- | --- |
| Invite / Invitation | 邀请 |
| Search | 搜索 |
| Email | 邮箱（label）/ 邮件（action） |
| Password | 密码 |
| Sign in / Log in | 登录 |
| Sign up | 注册 |
| Sign out / Log out | 退出登录 |
| Save / Cancel / Delete | 保存 / 取消 / 删除 |
| Confirm / Continue / Back | 确认 / 继续 / 返回 |
| Edit / New / Create / Add | 编辑 / 新建 / 创建 / 添加 |
| Remove / Send / Open / Close | 移除 / 发送 / 打开 / 关闭 |
| Preview / Download / Upload | 预览 / 下载 / 上传 |
| Done / Loading... | 完成 / 加载中... |
| Profile / Account / Appearance | 个人资料 / 账号 / 外观 |
| Theme / Language | 主题 / 语言 |
| Light / Dark / System | 浅色 / 深色 / 跟随系统 |
| Active / Archived | 活跃（或 启用）/ 已归档 |
| Status / Priority | 状态 / 优先级 |
| Assignee / Reporter | 负责人 / 报告人 |
| Description / Title | 描述 / 标题 |
| Date / Time | 日期 / 时间 |
| Today / Yesterday / Tomorrow | 今天 / 昨天 / 明天 |
| Empty / Failed / Success | 空 / 失败 / 成功 |
| Error / Warning | 错误 / 警告 |

### 角色名 + 状态名（小写英文，不翻）

这些是 schema-level 标识符，中文环境也保持小写英文：

- 角色：`owner` / `admin` / `member`
- Issue 状态：`backlog` / `todo` / `in_progress` / `in_review` / `done` / `blocked` / `cancelled`

UI 里展示这些值时保持英文（必要时用 code-style 包起来）：

- "你需要 owner 权限"
- "已切换到 in_progress"

### 词组组合规则

英文词（实体名 + 品牌名 + 缩写）与中文之间**加单空格**：

- "Create new issue" → "新建 issue"
- "Assign to agent" → "分配给智能体"
- "Configure runtime" → "配置运行时"
- "Stop daemon" → "停止守护进程"

### 复数与计数

i18next 用 `_one` / `_other`；中文不区分语法单复数，只填 `_other`。

```json
// en/issues.json
{
  "issue_count_one": "{{count}} issue",
  "issue_count_other": "{{count}} issues"
}

// zh-Hans/issues.json
{
  "issue_count_other": "{{count}} 个 issue"
}
```

常见计数格式：

- `{{count}} issues` → `{{count}} 个 issue`
- `{{count}} agents` → `{{count}} 个智能体`
- `{{count}} workspaces` → `{{count}} 个工作区`
- `{{count}} comments` → `{{count}} 条评论`
- `{{count}} members` → `{{count}} 位成员`
- `{{count}} skills` → `{{count}} 个 skill`

### 插值

用 `{{var}}` 形式。中文翻译可以调整位置以符合中文语序。

```json
// en
{ "welcome_message": "Welcome back, {{name}}!" }

// zh-Hans
{ "welcome_message": "欢迎回来，{{name}}！" }
```

### Key 命名约定

3 层嵌套：`feature.component.action`。

```json
{
  "feature_or_component": {
    "subcomponent_or_section": {
      "action_or_label": "..."
    }
  }
}
```

实例：

- `issues.toolbar.batch_update_success`
- `issues.detail.comment_form.placeholder`
- `inbox.empty.title`
- `settings.preferences.language.title`

### Web-only / Desktop-only 文案位置

- 共享文案：放 namespace JSON 顶层
- Web-only：放 `web` 段
- Desktop-only：放 `desktop` 段

参考 `auth.json`（`web` 段含 `prefer_desktop` / `desktop_handoff.*`）。

---

## 3. 中文风格

### 标点

- 中文用全角标点：`，。：；！？`
- 引号：用 `"..."`（直引号），与英文 source 保持一致。**不要**用 `「」` 或弯引号
- 省略号：用 `...`（三点）而非 `…`（单字符），与英文 source 保持一致
- 中英混排：英文词左右各加 1 个空格（详见词组组合规则）

### 风格原则

- **简洁直白**：避免翻译腔，"对于 X 来说"、"作为 X"、"我们的"
- **错误信息**：温和但明确，"无法保存修改" 优于 "保存修改失败了！"
- **按钮**：动词开头，2-4 字最佳。"取消"、"保存修改"、"立即同步"
- **Tooltip**：完整短句。"复制链接到剪贴板"
- **placeholder**：示例性提示。"输入 issue 标题..."

### 拿不准的时候去哪查

术语表没覆盖的词，按这个顺序查：

1. `apps/docs/content/docs/*.zh.mdx` —— CN voice 事实标准，20+ 篇高度一致
2. `packages/views/locales/zh-Hans/auth.json` 和 `editor.json` —— JSON 结构 + selector API 用法参考
3. `packages/views/auth/login-page.tsx` —— 组件层 selector API 调用参考
4. `packages/views/settings/components/preferences-tab.tsx` —— 语言切换器参考

---

## 修改这一页时

改本页规则的同时还要：

1. 把规则在相关 locale JSON / CLAUDE.md / docs 页面里同步落地
2. PR 描述里写明改了什么，方便 reviewer 检查下游是否跟着改了

本页是契约，其他文档不能 override。
