Multica Docs
Développeurs

Conventions

Source unique de vérité pour le nommage du code, le glossaire de traduction i18n et le guide de ton pour le chinois.

Cette page est la source unique de vérité pour le nommage du code, le glossaire de traduction i18n et le guide de ton pour le chinois. Tout ce qui se trouvait auparavant dans packages/views/locales/glossary.md ou dans des commentaires épars se trouve désormais ici.

Si vous écrivez du code Multica, modifiez une traduction ou rédigez des textes produit en chinois, c'est la page de référence.


1. Nommage du code

Routes

Les routes pré-espace de travail (celles qui existent avant que l'utilisateur n'entre dans un espace de travail) DOIVENT utiliser soit un seul mot, soit le motif /{noun}/{verb}.

  • /login, /inbox, /workspaces/new
  • /new-workspace, /create-team, /accept-invite

Les groupes de mots reliés par des traits d'union à la racine entrent en collision avec les slugs d'espace de travail choisis par les utilisateurs et imposent des audits sans fin des slugs réservés. Réserver le nom (workspaces) protège automatiquement tout le sous-arbre /workspaces/*.

Routes liées à un espace de travail

Elles se trouvent toujours sous /{slug}/{section}/{slug}/issues, /{slug}/agents, /{slug}/settings. Ne dupliquez jamais la logique de routage des espaces de travail ; utilisez useNavigation().push() depuis le code partagé, jamais les API de lien propres à un framework.

Packages et modules

Le monorepo impose des frontières strictes entre les packages :

PackagePeut dépendre deNe doit PAS dépendre de
packages/corerien de spécifique à une applicationreact-dom, localStorage, process.env, next/*, bibliothèques d'UI
packages/uirien@multica/core, logique métier
packages/viewscore/, ui/next/*, react-router-dom, stores
apps/web/platform/next/*autres applications
apps/desktop/.../platform/react-router-dom, electronautres applications
apps/mobile/types et fonctions pures de @multica/corepages React, stores et implémentations de plateforme de Web/Desktop

Si une logique apparaît dans les deux applications, elle DOIT être extraite dans un package partagé. Aucune exception pour une « petite » duplication. Mobile possède sa propre UI, sa propre couche de données et son propre processus de publication ; il ne partage que les types et les fonctions pures.

Fichiers et composants

  • Fichiers : kebab-case.tsx / kebab-case.ts (par ex. agent-row-actions.tsx)
  • Composants : PascalCase (par ex. AgentRowActions)
  • Hooks : useCamelCase (par ex. useWorkspaceId)
  • Tests : placés à côté du fichier, sous la forme <file>.test.ts(x)
  • Stores (Zustand) : <feature>-store.ts, exportés sous le nom use<Feature>Store

Base de données (Go + sqlc)

  • Tables : snake_case au singulier (user, workspace, agent_runtime)
  • Colonnes : snake_case (workspace_id, created_at, last_seen_at)
  • Clés étrangères : <table>_id
  • Booléens : is_<state> ou <state>_at (la forme horodatée est préférée pour les changements d'état)
  • Fichiers de migration : NNN_descriptive_name.up.sql + .down.sql — fournissez toujours les deux sens
  • Ne créez pas de clés étrangères en base de données et n'utilisez pas de suppressions ni de mises à jour en cascade ; garantissez les relations et le nettoyage dans la couche applicative.
  • Chaque index doit utiliser CREATE INDEX CONCURRENTLY ou CREATE UNIQUE INDEX CONCURRENTLY, chaque index concurrent étant placé dans son propre fichier de migration qui ne contient qu'une seule instruction.

Go

  • gofmt + go vet standard. Sans exception.
  • Les fichiers de handler reflètent le domaine : agent.go, auth.go, runtime.go
  • Tests : <file>_test.go placé à côté du fichier
  • Pour le parsing des UUID dans les handlers, suivez la règle du AGENTS.md racine — parseUUIDOrBadRequest pour les entrées aux frontières, parseUUID (qui panique) pour les allers-retours de confiance, et jamais util.ParseUUID directement sans vérifier l'erreur.

TypeScript

  • Les réponses d'API qui transitent sur le réseau sont en snake_case ; le client API les convertit en camelCase à la frontière. Dans le code TS, toujours en camelCase.
  • Types : PascalCase (Issue, AgentRuntime) ; jamais de IPrefix, jamais de suffixe _t.
  • Enums : préférez les unions de littéraux de chaîne ; réservez enum aux cas qui doivent pouvoir être parcourus dynamiquement.
  • Clés TanStack Query : fonctions factory dans <feature>/queries.ts, par ex. issueKeys.detail(id).

Frontières d'API

  • Analysez les réponses réseau avec parseWithFallback et les schémas zod de packages/core/api/schema.ts ; ne les castez pas directement avec as T.
  • Lorsque vous ajoutez ou modifiez un endpoint, mettez à jour son schéma et couvrez les champs manquants ou malformés dans les tests.
  • L'UI en aval doit fournir des valeurs par défaut pour les champs optionnels, et chaque switch sur un enum serveur doit inclure une branche default.
  • Un client Desktop installé peut se connecter à un backend plus récent ; ne supposez jamais que les versions du frontend et du backend correspondent toujours.

Noms d'affichage des runtimes

AgentRuntime.name est le nom technique brut du daemon (par ex. Codex (host)) ; l'alias de l'utilisateur se trouve dans custom_name. Un texte visible par l'utilisateur ne doit jamais afficher runtime.name directement — utilisez les helpers partagés pour que les alias et le fournisseur restent cohérents (MUL-5248, #5260) :

  • Libellé de runtime autonome (listes, chips, boîtes de dialogue de confirmation, titres de document) : runtimeDisplayLabel(runtime) → alias + fournisseur, avec repli sur le nom du daemon.
  • Lorsqu'une icône ou un texte de fournisseur figure déjà à côté : runtimeDisplayName(runtime) → alias seul, sans répéter le fournisseur.
  • Dans un groupe de machine : l'en-tête de la machine utilise machine.title, les lignes enfants utilisent runtimeRowLabel(runtime, machine.title).
  • Les sélecteurs de runtime regroupent par machine via buildRuntimeMachines ; ne construisez pas une liste plate de noms bruts.

Le runtime.name brut n'est autorisé que pour l'identité interne — parsing du nom d'hôte, regroupement, texte indexé pour la recherche et payloads de protocole — jamais pour du texte JSX, des paramètres i18n, des libellés de <Select> ou des titres de fenêtre.

Clés de tâche

Chaque tâche possède une clé lisible comme MUL-123 : le issue_prefix de l'espace de travail (lettres majuscules et chiffres, généralement 3 caractères, 10 au maximum) + un numéro de séquence. Les administrateurs de l'espace de travail peuvent modifier le préfixe dans Paramètres → Général ; ce changement renumérote toutes les tâches existantes, si bien que les références externes qui contiennent l'ancien préfixe (titres de PR, noms de branche, liens dans la documentation et les messageries) ne se résolvent plus.

Commentaires dans le code

Anglais uniquement. Le dépôt l'impose pour Go comme pour TypeScript. Si vous trouvez un commentaire en chinois dans le code, c'est un bug — remplacez-le.

Messages de commit

Format conventionnel : feat(scope), fix(scope), refactor(scope), docs, test(scope), chore(scope). Des commits atomiques, regroupés par intention.


2. Glossaire de traduction i18n

Voici le glossaire obligatoire pour toute PR de traduction. Il se trouvait auparavant dans packages/views/locales/glossary.md ; ce fichier a été supprimé et cette page le remplace.

La distinction essentielle : nom courant vs terme propre à Multica

Les noms de produit de Multica se répartissent en deux catégories :

  • Nom courant — le mot qu'un utilisateur emploierait à voix haute pour le désigner. Traduisez-le entièrement, qu'il s'agisse ou non d'une entité de base de données : issue → 任务, workspace → 工作区, project → 项目.
  • Terme propre à Multica — un concept qu'aucun mot local ne porte (skill), ou un identifiant de niveau schéma qu'un utilisateur peut avoir à saisir ou à faire correspondre (todo, in_progress, task_id). Écrivez-le en anglais minuscule pour qu'il se lise comme un nom de type.

Les pages chinoises apps/docs/content/docs/*.zh.mdx sont la norme de fait pour le ton de tout le reste de cette page. Le texte des pages *.zh.mdx, *.ja.mdx et *.ko.mdx suit désormais aussi le tableau ci-dessous.

issue est la tâche du produit — traduisez-le

issue est le nom produit anglais de ce qu'un utilisateur crée et de ce sur quoi un agent travaille. Dans toutes les autres langues, c'est le mot courant pour « tâche » :

Entitéenzh-Hansjakofr
l'unité de travail suivie (issue)Issue任务タスク태스크Tâche
un enregistrement d'exécution d'agent (task dans l'API / la base de données)Run运行実行실행Exécution

Ces deux concepts sont visibles par l'utilisateur et ne sont pas la même chose : une tâche peut avoir plusieurs exécutions. Ne laissez jamais une langue écrire les deux avec le même mot. Task n'est plus un nom de produit visible par l'utilisateur pour une exécution d'agent ; il ne subsiste que comme identifiant interne établi.

Ce qui ne change pas :

  • Les champs d'API / de base de données restent issue / task / skill partout : issue_status, task_id, skill_uuid. La prose destinée aux développeurs appelle l'objet produit un Run et peut préciser « Run (task_id dans l'API) » lorsque l'identifiant compte.
  • Les références de code et les commandes littérales restent en anglais : multica issue ..., la commande slash /issue de Slack et de Lark.
  • skill reste en anglais minuscule dans le texte chinois — c'est un concept propre à Multica sans terme chinois établi ; les titres peuvent l'écrire avec une majuscule, Skills.
  • issue au sens de « problème » (santé du runtime) est un nom ordinaire, pas l'entité : {{count}} issues sur une carte de machine devient {{count}} 个异常 / 問題 {{count}} 件 / 문제 {{count}}개, jamais le mot de l'entité.

Pourquoi issue est traduit alors que skill ne l'est pas : les utilisateurs créent et lisent des tâches toute la journée, et « issue » n'a aucun sens en chinois, en japonais ou en coréen en dehors du jargon des développeurs. Le mot courant pour « tâche » est celui que les gens emploient déjà pour cet objet. skill est un concept propre à Multica, pour lequel aucun mot local ne porte ce sens.

Les autres noms de produit suivent le même critère, « traduire ce qui a un mot local établi » :

  • project → "项目" : mot chinois courant et bien établi. Feishu / Tower / Teambition / PingCode / GitHub Projects — tous les produits chinois le traduisent. Aucun produit ne conserve project dans un contexte chinois.
  • autopilot → "自动化" : en chinois, « autopilot » évoque le « 自动驾驶 » de Tesla et ne correspond pas à ce que fait la fonctionnalité (lancer des exécutions d'agent selon une planification). Notion et Feishu utilisent tous deux « 自动化 » ; c'est le consensus du secteur.

Ne pas traduire — marques et acronymes

CatégorieTermes
MarquesMultica, GitHub, Slack, Google, Anthropic, OpenAI, Claude, Codex, Cursor, Linear, Jira
AcronymesAPI, CLI, URL, SDK, OAuth, JWT, SSO, WebSocket, HTTP, JSON, YAML, SQL

Traduire entièrement — concepts

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

Traduire entièrement — mots génériques de l'UI

AnglaisChinois
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活跃 (or 启用) / 已归档
Status / Priority状态 / 优先级
Assignee / Reporter负责人 / 报告人
Description / Title描述 / 标题
Date / Time日期 / 时间
Today / Yesterday / Tomorrow今天 / 昨天 / 明天
Empty / Failed / Success空 / 失败 / 成功
Error / Warning错误 / 警告

Rôles et enums de statut (anglais minuscule, non traduits)

Ce sont des identifiants de niveau schéma ; écrivez-les en anglais minuscule, même dans un contexte chinois.

  • Rôles : owner / admin / member
  • Statut de tâche : backlog / todo / in_progress / in_review / done / blocked / cancelled
  • Catégorie de statut de tâche : unstarted / started / done / closed

Dans l'UI, affichez-les en anglais (éventuellement entourés en code-style) :

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

Règles de combinaison des mots

Mettez toujours un seul espace entre un mot anglais (entité / marque / acronyme) et le chinois qui l'entoure :

  • "Create new issue" → "新建任务"(任务 est du chinois, donc pas d'espace)
  • "Assign to agent" → "分配给智能体"
  • "Configure runtime" → "配置运行时"
  • "Stop daemon" → "停止守护进程"

Pluriels et nombres

i18next utilise _one / _other ; le chinois n'a pas de nombre grammatical, ne renseignez donc que _other.

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

// zh-Hans/issues.json
{
  "issue_count_other": "{{count}} 个任务"
}

Formats de nombre courants :

  • {{count}} issues{{count}} 个任务
  • {{count}} agents{{count}} 个智能体
  • {{count}} workspaces{{count}} 个工作区
  • {{count}} comments{{count}} 条评论
  • {{count}} members{{count}} 位成员
  • {{count}} skills{{count}} 个 skill

Interpolation

Utilisez {{var}}. Les traductions chinoises peuvent changer l'ordre des éléments pour que la phrase se lise naturellement.

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

// zh-Hans
{ "welcome_message": "欢迎回来,{{name}}!" }

Nommage des clés de traduction

Trois niveaux d'imbrication : feature.component.action.

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

Exemples :

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

Textes réservés au Web ou au Desktop

  • Textes partagés : au premier niveau du JSON du namespace
  • Web uniquement : section web
  • Desktop uniquement : section desktop

Consultez auth.json pour l'exemple de référence (la section web contient prefer_desktop / desktop_handoff.*).


3. Ton et style en chinois

Ponctuation

  • Ponctuation pleine chasse en chinois : ,。:;!?
  • Guillemets : guillemets doubles droits "...", comme dans la source anglaise. N'utilisez ni 「」 ni les guillemets typographiques.
  • Points de suspension : trois points ... et non le caractère unique . Suivez la source anglaise.
  • Mélange chinois-anglais : un seul espace de chaque côté du mot anglais (voir les règles de combinaison des mots).

Principes de style

  • Concis et direct. Évitez les tournures de traduction : "对于 X 来说"、"作为 X"、"我们的"。
  • Messages d'erreur : doux mais clairs. "无法保存修改" est préférable à "保存修改失败了!".
  • Boutons : verbe en premier, 2 à 4 caractères. "取消"、"保存修改"、"立即同步".
  • Infobulles : une phrase courte et complète. "复制链接到剪贴板".
  • Placeholders : sous forme d'exemple. "输入任务标题...".

Descriptions dans l'UI

Les descriptions sont facultatives et omises par défaut. Avant d'en ajouter une, demandez-vous : qu'est-ce que l'utilisateur comprendrait mal ou ferait de travers sans cette phrase ? Si le titre, le libellé, le contrôle, la valeur ou le bouton y répond déjà, omettez la phrase.

  • Énoncez un fait une seule fois, à côté du contrôle concerné. Ne le répétez pas dans les descriptions de la page, de la section, de la ligne, de l'état vide et de la boîte de dialogue.
  • Préférez un libellé précis ou un exemple à un paragraphe qui explique une action évidente. Évitez les instructions génériques comme « Create one to get started », « Click below » ou « You can change this later », sauf si elles lèvent une réelle ambiguïté.
  • Gardez visibles, lorsqu'ils sont pertinents, les permissions, le coût, les conséquences destructrices, les prérequis d'exécution, les contraintes de saisie et la reprise après erreur. Ne les cachez pas dans une aide qui n'apparaît qu'au survol.
  • N'affichez des indications d'introduction que là où elles sont nécessaires. Placez l'utilisation avancée et les diagnostics dans une aide explicite et accessible plutôt que dans le corps de page par défaut.
  • Conservez les libellés de champ, les noms accessibles et les associations de description nécessaires. Ne déplacez pas en bloc une prose visible redondante vers du texte réservé aux lecteurs d'écran.
  • Relisez ensemble les textes anglais et traduits, y compris les chaînes indépendantes de l'application mobile. En revue de PR, vérifiez l'information ajoutée, la répétition sur un même écran, les conditions d'affichage et les contraintes préservées. La longueur est un signal de revue, pas une règle de suppression automatique.

Les composants de paramètres partagés acceptent déjà des descriptions facultatives. Les exemples et les nouveaux points d'appel doivent les omettre sauf justification ; n'ajoutez pas de props de description obligatoires ni de politique de rédaction distincte.

En cas de doute

Lorsque le glossaire ne couvre pas un terme, consultez :

  1. apps/docs/content/docs/*.zh.mdx — la norme de fait pour le ton en chinois, plus de 20 pages de traduction cohérente
  2. packages/views/locales/zh-Hans/auth.json et editor.json — structure JSON + modèles d'API de sélecteur
  3. packages/views/auth/login-page.tsx — point d'appel de l'API de sélecteur au niveau d'un composant
  4. packages/views/settings/components/preferences-tab.tsx — référence pour le sélecteur de langue

Mettre à jour cette page

Si vous modifiez une règle ici, pensez aussi à :

  1. L'appliquer dans les JSON de langue, AGENTS.md ou la page de documentation concernés
  2. Signaler le changement dans la description de la PR, pour que les relecteurs sachent qu'ils doivent vérifier la propagation en aval

Cette page est le contrat ; rien d'autre ne prévaut sur elle.