Skip to content

Commit cc20bb6

Browse files
sjyangkevinAnkurdeewan
authored andcommitted
add SKILL.md and zh-CN agent skill instruction (apache#62059)
* add zh-CN agent skill instruction resolve conflict in pre-commit, and soften wording in SKILL.md to instruct agent take locale-specific guidelines with higher precedence * add prek hook to list namespace file and update SKILL.md, remove i18n policy reference, and fix table * add shorten license to zh-CN.md * soften the wording and instruct agent to take locale-specific instruction with more precedence * fix pre-commit hook add license, use SKILL instead of SKILLs * fix insert license hook and add shorten license after yaml formatter * fix markdown lint and update SKILL.md
1 parent b718620 commit cc20bb6

4 files changed

Lines changed: 353 additions & 5 deletions

File tree

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
name: airflow-translations
3+
description: >
4+
Translate, review, and maintain Apache Airflow i18n locale strings in JSON
5+
translation files. Use when working with internationalization, localization,
6+
or translation tasks in airflow-core/src/airflow/ui/public/i18n/locales/.
7+
Covers Airflow terminology conventions and translation guidelines.
8+
license: Apache-2.0
9+
---
10+
<!-- SPDX-License-Identifier: Apache-2.0 https://www.apache.org/licenses/LICENSE-2.0 -->
11+
12+
# Airflow Translations
13+
14+
## Locale-Specific Guidelines
15+
16+
Before translating, you **must** read the locale-specific guideline file for
17+
the target language. Locale files are located at `locales/<locale-name>.md`
18+
relative to this skill directory.
19+
20+
Match the translation task to the correct locale file using the table below:
21+
22+
| Locale Code | Language | Guideline File |
23+
| ----------- | ----------------------- | ------------------------------- |
24+
| `ar` | Arabic | [locales/ar.md](locales/ar.md) |
25+
| `ca` | Catalan | [locales/ca.md](locales/ca.md) |
26+
| `de` | German | [locales/de.md](locales/de.md) |
27+
| `el` | Greek | [locales/el.md](locales/el.md) |
28+
| `es` | Spanish | [locales/es.md](locales/es.md) |
29+
| `fr` | French | [locales/fr.md](locales/fr.md) |
30+
| `he` | Hebrew | [locales/he.md](locales/he.md) |
31+
| `hi` | Hindi | [locales/hi.md](locales/hi.md) |
32+
| `hu` | Hungarian | [locales/hu.md](locales/hu.md) |
33+
| `it` | Italian | [locales/it.md](locales/it.md) |
34+
| `ja` | Japanese | [locales/ja.md](locales/ja.md) |
35+
| `ko` | Korean | [locales/ko.md](locales/ko.md) |
36+
| `nl` | Dutch | [locales/nl.md](locales/nl.md) |
37+
| `pl` | Polish | [locales/pl.md](locales/pl.md) |
38+
| `pt` | Portuguese | [locales/pt.md](locales/pt.md) |
39+
| `th` | Thai | [locales/th.md](locales/th.md) |
40+
| `tr` | Turkish | [locales/tr.md](locales/tr.md) |
41+
| `zh-CN` | Simplified Chinese | [locales/zh-CN.md](locales/zh-CN.md) |
42+
| `zh-TW` | Traditional Chinese | [locales/zh-TW.md](locales/zh-TW.md) |
43+
44+
If the target locale file does not yet exist, follow only the global rules in this document.
45+
When a locale-specific guideline conflicts with a global rule, the **locale-specific
46+
guideline takes precedence**.
47+
48+
## Translation File Structure
49+
50+
All translation files are JSON files located at:
51+
52+
```
53+
airflow-core/src/airflow/ui/public/i18n/locales/<locale-name>/
54+
```
55+
56+
Each locale directory contains namespace JSON files that mirror the English
57+
locale (`en/`). The English locale is the **default locale** and the primary
58+
source for all translations. The current namespace files are:
59+
60+
<!-- START namespace-files, please keep comment here to allow auto update -->
61+
`admin.json`, `assets.json`, `browse.json`, `common.json`, `components.json`, `dag.json`, `dags.json`, `dashboard.json`, `hitl.json`, `tasks.json`
62+
<!-- END namespace-files, please keep comment here to allow auto update -->
63+
64+
## Translation Principles
65+
66+
1. **Concise and clear** — Translations are used in UI elements (buttons,
67+
labels, tooltips). Keep them short and suitable for constrained UI space.
68+
2. **Consistent** — Always use the same translated term for the same English
69+
term. Refer to the glossary in your locale file.
70+
3. **Accurate** — Maintain the original meaning and intent.
71+
4. **Neutral tone** — Language should be polite and neutral.
72+
5. **Local conventions** — Respect date formats, number formatting, and
73+
formal/informal tone as appropriate for the locale.
74+
75+
## Do-Not-Translate Terms
76+
77+
The following terms should remain in English by default. Locale-specific
78+
guidelines may override individual entries where established conventions exist:
79+
80+
| Term | Reason |
81+
| ------------------------ | ------------------------------------------------------------- |
82+
| `Airflow` | Product name |
83+
| `Dag` / `Dags` | Airflow convention; always use `Dag`, never `DAG` |
84+
| `XCom` / `XComs` | Airflow cross-communication mechanism name |
85+
| `Provider` / `Providers` | Airflow extension package name |
86+
| `REST API` | Standard technical term |
87+
| `JSON` | Standard technical format name |
88+
| `ID` | Universal abbreviation |
89+
| `PID` | Unix process identifier |
90+
| `UTC` | Time standard |
91+
| `Schema` | Database term (keep unless locale has established convention) |
92+
93+
## Variable and Placeholder Handling
94+
95+
Translation strings use the `{{variable}}` interpolation syntax (i18next
96+
format):
97+
98+
- **Never translate** variable names inside `{{...}}`.
99+
- **Never remove** any `{{variable}}` placeholders.
100+
- **Reorder** placeholders as needed to match natural word order.
101+
- **Preserve** exact variable casing (e.g., `{{dagDisplayName}}`).
102+
103+
## Plural Forms
104+
105+
Airflow uses i18next plural suffixes (`_one`, `_other`, and optionally `_zero`,
106+
`_two`, `_few`, `_many`). Provide translations for **all** plural suffixes
107+
relevant to the language you provide translation for.
108+
109+
## Hotkeys
110+
111+
Hotkey values (e.g., `"hotkey": "e"`) are literal key bindings and should
112+
**not** be translated unless the locale-specific guideline specifies otherwise.
113+
114+
## Translation Workflow
115+
116+
1. **Read** the locale-specific guideline (`locales/<locale-name>.md`).
117+
2. **Identify** missing translations — use `--add-missing` to generate stubs
118+
prefixed with `TODO: translate`:
119+
120+
```bash
121+
breeze ui check-translation-completeness --language <locale-name> --add-missing
122+
```
123+
124+
3. **Translate** the `TODO: translate` entries using this guide and the locale
125+
glossary.
126+
4. **Remove** extra keys not present in the English source:
127+
128+
```bash
129+
breeze ui check-translation-completeness --language <locale-name> --remove-extra
130+
```
131+
132+
5. **Validate** completeness:
133+
134+
```bash
135+
breeze ui check-translation-completeness --language <locale-name>
136+
```
137+
138+
## Common Airflow Terms
139+
140+
The following terms appear frequently in the English source files. Each locale
141+
glossary should define consistent translations for them. The **Context** column
142+
disambiguates terms that may have different meanings outside of Airflow:
143+
144+
| English Term | Context |
145+
| -------------------- | ---------------------------------------- |
146+
| Task | Unit of work in a Dag |
147+
| Task Instance | Single run of a Task |
148+
| Task Group | Logical grouping of Tasks |
149+
| Dag Run | Single execution of a Dag |
150+
| Operator | Type/class that defines a Task |
151+
| Trigger | Event or mechanism that starts a run |
152+
| Trigger Rule | Condition that determines Task execution |
153+
| Triggerer | Airflow component that handles triggers |
154+
| Schedule / Scheduler | Timing configuration / Airflow component |
155+
| Backfill | Retroactive execution of Dag Runs |
156+
| Asset | Data dependency tracked by Airflow |
157+
| Asset Event | Notification that an Asset was updated |
158+
| Connection | External system credentials |
159+
| Variable | Key-value configuration store |
160+
| Pool | Resource constraint mechanism |
161+
| Plugin | Extensibility mechanism |
162+
| Executor | Component that runs Tasks |
163+
| Queue | Execution queue for Tasks |
164+
| Audit Log | Record of system events |
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<!-- SPDX-License-Identifier: Apache-2.0 https://www.apache.org/licenses/LICENSE-2.0 -->
2+
# Simplified Chinese (zh-CN)
3+
4+
This document provides locale-specific instructions for translating English
5+
Airflow UI strings into Simplified Chinese. It inherits all global rules from
6+
the parent [SKILL.md](../SKILL.md).
7+
8+
## Plural Forms
9+
10+
Simplified Chinese **does not** distinguish between singular and plural forms.
11+
Use the **same translation** for both `_one` and `_other` suffixes:
12+
13+
**English source:**
14+
15+
```json
16+
"dagRun_one": "Dag Run",
17+
"dagRun_other": "Dag Runs"
18+
```
19+
20+
**Correct** — identical for both:
21+
22+
```json
23+
"dagRun_one": "Dag 执行",
24+
"dagRun_other": "Dag 执行"
25+
```
26+
27+
## Spacing Rules
28+
29+
Insert a **half-width space** between Chinese characters and adjacent
30+
English words, numbers, or symbols:
31+
32+
**Correct:**
33+
34+
```json
35+
"Dag 执行" // space between English and Chinese
36+
"最近 12 小时" // space around numbers
37+
"连接 ID" // space before abbreviation
38+
"{{count}} 个连接" // space after placeholder
39+
```
40+
41+
**Incorrect:**
42+
43+
```json
44+
"Dag执行" // missing space
45+
"最近12小时" // missing space around numbers
46+
```
47+
48+
## Punctuation
49+
50+
- Use **full-width** punctuation for Chinese sentences: `` `` `` `` ``
51+
- Use **half-width** punctuation for content within English terms, JSON, or
52+
code: `,` `.` `:` `?`
53+
- Use **full-width** parentheses for Chinese context: `` ``
54+
- Use **half-width** parentheses when wrapping English or variables: `(` `)`
55+
56+
**Correct** — full-width for Chinese sentences:
57+
58+
```json
59+
"confirmation": "确定要删除 {{resourceName}} 吗?此操作无法还原。"
60+
```
61+
62+
**Correct** — half-width for English/variable context:
63+
64+
```json
65+
"tooltip": "按下 {{hotkey}} 切换展开"
66+
```
67+
68+
## Measure Words (量词)
69+
70+
Chinese requires **measure words** (量词) between numbers and nouns. Use the
71+
appropriate measure word for each context:
72+
73+
| Measure Word | Usage | Example |
74+
|---|---|---|
75+
| `` | General objects (connections, variables, errors) | `删除 {{count}} 个连接` |
76+
| `` | Occurrences (runs, executions, attempts) | `最近 {{count}} 次 Dag 执行` |
77+
| `` | List items | `+ 其他 {{count}} 项` |
78+
79+
## Tone and Formality
80+
81+
- Use **neutral, slightly formal** register.
82+
- Use `` (formal "you") in confirmations and destructive actions:
83+
`"您即将删除以下连接:"`.
84+
- Avoid colloquial or overly casual expressions.
85+
- Keep translations **concise** — these are UI labels and button text.
86+
87+
## Variable and Placeholder Examples
88+
89+
Preserve all `{{variable}}` placeholders. Reorder as needed for natural Chinese
90+
word order:
91+
92+
**English source:**
93+
94+
```json
95+
"title": "Mark {{type}} as {{state}}"
96+
```
97+
98+
**Correct** — placeholders preserved:
99+
100+
```json
101+
"title": "标记 {{type}} 为 {{state}}"
102+
```
103+
104+
**Incorrect** — variable names translated:
105+
106+
```json
107+
"title": "标记 {{类型}} 为 {{状态}}"
108+
```
109+
110+
## Terminology Reference
111+
112+
The established zh-CN translations are defined in the existing locale files.
113+
Before translating, **read the existing zh-CN JSON files** to learn the
114+
established terminology:
115+
116+
```
117+
airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/
118+
```
119+
120+
Use the translations found in these files as the authoritative glossary. When
121+
translating a term, check how it has been translated elsewhere in the locale
122+
to maintain consistency. If a term has not been translated yet, refer to the
123+
English source in `en/` and apply the rules in this document.

.pre-commit-config.yaml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ repos:
5454
^\.github/.*\.md$|
5555
^airflow-core/tests/system/README\.md$
5656
exclude:
57-
(?x)
58-
.github/PULL_REQUEST_TEMPLATE\.md$
57+
(?x)
58+
.github/PULL_REQUEST_TEMPLATE\.md$|
59+
.github/skills/
5960
args:
6061
- "--maxlevel"
6162
- "2"
@@ -173,7 +174,7 @@ repos:
173174
^\.claude/|
174175
AGENTS\.md$|
175176
CLAUDE\.md$|
176-
SKILLS\.md$|
177+
SKILL\.md$|
177178
^scripts/ci/license-templates/
178179
- id: insert-license
179180
name: Add short license for agentic Markdown files
@@ -189,9 +190,11 @@ repos:
189190
^\.claude/|
190191
AGENTS\.md$|
191192
CLAUDE\.md$|
192-
SKILLS\.md$
193+
SKILL\.md$
193194
exclude:
194-
^scripts/ci/license-templates/
195+
(?x)
196+
^scripts/ci/license-templates/|
197+
^\.github/skills/airflow-translations/SKILL\.md$
195198
- id: insert-license
196199
name: Add license for all other files
197200
args:
@@ -760,6 +763,15 @@ repos:
760763
files: ^scripts/ci/docker-compose/integration-.*\.yml$|^contributing-docs/testing/integration_tests\.rst$
761764
require_serial: true
762765
pass_filenames: false
766+
- id: sync-translation-namespaces
767+
name: Sync translation namespace file list
768+
entry: ./scripts/ci/prek/sync_translation_namespaces.py
769+
language: python
770+
files: >
771+
(?x)
772+
^airflow-core/src/airflow/ui/public/i18n/locales/en/.*\.json$|
773+
^\.github/skills/airflow-translations/SKILL\.md$
774+
pass_filenames: false
763775
- id: update-pyproject-toml
764776
name: Update Airflow's meta-package pyproject.toml
765777
language: python
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python3
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
"""Sync the translation namespace file list in SKILL.md with the English locale directory."""
19+
20+
from __future__ import annotations
21+
22+
import sys
23+
from pathlib import Path
24+
25+
sys.path.insert(0, str(Path(__file__).parent.resolve()))
26+
from common_prek_utils import AIRFLOW_ROOT_PATH, insert_documentation
27+
28+
EN_LOCALE_DIR = (
29+
AIRFLOW_ROOT_PATH / "airflow-core" / "src" / "airflow" / "ui" / "public" / "i18n" / "locales" / "en"
30+
)
31+
SKILL_FILE = AIRFLOW_ROOT_PATH / ".github" / "skills" / "airflow-translations" / "SKILL.md"
32+
33+
START_MARKER = "<!-- START namespace-files, please keep comment here to allow auto update -->"
34+
END_MARKER = "<!-- END namespace-files, please keep comment here to allow auto update -->"
35+
36+
if __name__ == "__main__":
37+
json_files = sorted(p.name for p in EN_LOCALE_DIR.glob("*.json"))
38+
if not json_files:
39+
print(f"No JSON files found in {EN_LOCALE_DIR}")
40+
sys.exit(1)
41+
42+
formatted = ", ".join(f"`{f}`" for f in json_files) + "\n"
43+
insert_documentation(
44+
file_path=SKILL_FILE,
45+
content=[formatted],
46+
header=START_MARKER,
47+
footer=END_MARKER,
48+
extra_information="translation namespace file list",
49+
)

0 commit comments

Comments
 (0)