Skip to content

Commit e2093d6

Browse files
authored
Merge pull request #346 from emavgl/add_wallets
Add wallets and profiles
2 parents 1eaae2e + 2e390b6 commit e2093d6

135 files changed

Lines changed: 25153 additions & 4352 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/translate/SKILL.md

Lines changed: 135 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,71 +6,166 @@ argument-hint: "[locale-file]"
66

77
# Skill: translate
88

9-
Translate untranslated strings in a locale JSON file for the Oinkoin app.
9+
Translate missing strings key-by-key across all locale files (or a specific one).
1010

1111
## Usage
1212
```
13-
/translate <locale-file>
13+
/translate [locale-file]
1414
```
15-
Example: `/translate assets/locales/it.json`
16-
17-
If no file is specified, address all the locale files
15+
- `/translate` — processes all locale files
16+
- `/translate it.json` — processes Italian only
1817

1918
---
2019

2120
## How translations work in this project
2221

23-
- All locale files live in `assets/locales/` (e.g. `it.json`, `de.json`, `pt-BR.json`).
24-
- `assets/locales/en-US.json` is the **source of truth**: every key AND its English value are listed there.
25-
- Every other locale file has the **same keys**. A string is **untranslated** when its value is identical to its key (i.e. it was never localised and still reads in English).
26-
- A string is **already translated** when its value differs from its key. **Never touch those.**
22+
- All locale files live in `assets/locales/`.
23+
- `assets/locales/en-US.json` is the **source of truth**.
24+
- A string is **untranslated** when its value equals its key in a locale file.
25+
- `en-GB.json` is always skipped (near-identical to US English).
26+
27+
---
2728

28-
## Step-by-step instructions
29+
## Workflow
2930

30-
### 0. Sync keys with the codebase (always run first)
31-
Run the sync script from the project root to ensure `en-US.json` is up-to-date and stale keys are removed from all locale files:
32-
```
31+
This skill uses `_automated_translation.json` at the project root to track context for every string. **Always check this file before translating.**
32+
33+
### Step 0 — Sync keys and ensure tracking file is current
34+
```bash
3335
python3 scripts/update_en_strings.py
3436
```
35-
This regenerates `en-US.json` from all `.i18n` strings found in `lib/`, and removes obsolete keys from every other locale file. Run it before translating so you are working against the current set of keys.
3637

37-
### 1. Read the target locale file
38-
Read the full file specified by the user.
38+
Then verify tracking file is in sync:
39+
```bash
40+
# If keys were added/removed, regenerate the tracking file (see CLAUDE.md for script)
41+
```
42+
43+
### Step 1 — Discover what needs translating
44+
Run the discovery script to get a structured list of every key that is missing in one or more locale files:
45+
46+
```bash
47+
# All locales:
48+
python3 scripts/find_missing_translations.py
49+
50+
# Specific locale(s):
51+
python3 scripts/find_missing_translations.py --locale it.json
52+
python3 scripts/find_missing_translations.py --locale it.json --locale de.json
53+
```
54+
55+
Output is a JSON array:
56+
```json
57+
[
58+
{ "key": "Apply", "missing_locales": ["de.json", "fr.json", "it.json"] },
59+
{ "key": "Amount (Ascending)", "missing_locales": ["it.json"] }
60+
]
61+
```
62+
63+
If the array is empty, tell the user everything is translated and stop.
64+
65+
### Step 2 — Process key by key
66+
67+
For **each entry** in the discovery output:
68+
69+
**2a. Check _automated_translation.json for context**
70+
71+
Look up the key in `_automated_translation.json`:
72+
```bash
73+
python3 -c "import json; d=json.load(open('_automated_translation.json')); print(json.dumps(d['keys']['your_key'], indent=2))"
74+
```
75+
76+
Three possibilities:
77+
78+
**Status = "verified"** — Context is documented, proceed to translation (2c)
79+
80+
**Status = "pending"** — Context not yet researched, do research first (2b)
81+
82+
**Status = "skip"** — Don't translate (brand names, technical terms, universal)
83+
84+
**2b. If pending: Research and document context**
85+
86+
Search the Dart source to understand where the key is used:
87+
```bash
88+
grep -rn "Key text here" lib/
89+
```
90+
91+
Read the surrounding code (5-10 lines before/after) to understand:
92+
- **Page context**: Settings, Wallets, Records, Currencies, Categories, etc.?
93+
- **Component context**: Button label, dropdown option, form field, error message, dialog title, description text?
94+
- **User perspective**: What would the user see on screen? What does this word mean in that UI context?
95+
96+
**Example**:
97+
- "Left" in a currency symbol position dropdown = positional (left of amount), not directional
98+
- Context changes translation from simple directional to positional description
99+
100+
Update `_automated_translation.json` with findings:
101+
```json
102+
{
103+
"keys": {
104+
"Left": {
105+
"key": "Left",
106+
"context": "Currency symbol position option",
107+
"file": "lib/settings/constants/preferences-options.dart:136",
108+
"page": "Settings > Currency Formatting",
109+
"component": "currencySymbolPosition dropdown option",
110+
"meaning": "Position the currency symbol to the LEFT of the amount (e.g., $100 vs 100$)",
111+
"notes": "Positional context - pair with 'Default' and 'Right' options",
112+
"status": "verified"
113+
}
114+
}
115+
}
116+
```
117+
118+
**2c. Translate into all missing locales at once**
119+
120+
With verified context in mind, produce the most natural translation for every locale in `missing_locales`:
121+
- **Context is the source of truth**: Use documented meaning, not literal word
122+
- Keep placeholders exactly as-is: `%s`, `%d`, `%1$s`, etc.
123+
- Match tone/terminology of already-translated strings in the same locale file
124+
- Strings with status="skip" should be kept as English (e.g., "Oinkoin Pro", "PIN", "CSV")
125+
- If the word is identical in English and target language, verify it's correct in context (often fine for tech terms)
126+
127+
**2d. Write translations immediately**
128+
129+
Apply all translations for this key to affected locale files in one batch:
130+
```bash
131+
python3 scripts/write_translations.py <<'EOF'
132+
{
133+
"de.json": { "Apply": "Anwenden" },
134+
"fr.json": { "Apply": "Appliquer" },
135+
"it.json": { "Apply": "Applica" }
136+
}
137+
EOF
138+
```
39139

40-
### 2. Identify untranslated strings
41-
A string is untranslated when `value == key`. Collect every such entry.
140+
The script only overwrites values that still equal their key (untranslated). Already-translated strings are never touched.
42141

43-
If there are no untranslated strings, tell the user and stop.
142+
### Step 3 — Continue with the next key
143+
Repeat Step 2 for every entry in the discovery output.
44144

45-
### 3. For each untranslated string — look up context before translating
46-
Do **not** guess from the key text alone. For each untranslated key:
145+
### Step 4 — Report
146+
After processing all keys, print a compact summary table:
47147

48-
- Search the Dart source code (Grep in `lib/`) for the exact key string to find where it is used.
49-
- Look at the surrounding widget/function/page to understand the context (e.g. is it a button label, a dialog title, an error message, a settings toggle description?).
50-
- Only then choose the most natural, contextually appropriate translation for the target language.
148+
| Key | Locale | Translation |
149+
|-----|--------|-------------|
150+
| Apply | it.json | Applica |
151+
| Apply | de.json | Anwenden |
152+
||||
51153

52-
### 4. Write the translated strings
53-
Edit the locale file, replacing only the untranslated values. Keep every other entry byte-for-byte identical.
154+
---
54155

55-
### 5. Report what changed
56-
After editing, print a compact table of the strings you translated:
156+
## Helper scripts reference
57157

58-
| Key | Translation |
59-
|-----|-------------|
60-
|||
158+
| Script | Purpose |
159+
|--------|---------|
160+
| `scripts/update_en_strings.py` | Sync `en-US.json` from source code and remove stale keys from all locales |
161+
| `scripts/find_missing_translations.py` | List every key that is untranslated in one or more locales |
162+
| `scripts/write_translations.py` | Apply a batch of translations from stdin JSON to locale files |
61163

62164
---
63165

64166
## Important rules
65167

66168
- **Never modify already-translated strings** (value ≠ key).
67169
- **Never change keys** — only values.
68-
- Preserve placeholders exactly as written: `%s`, `%d`, `%1$s`, etc.
69-
- Match the tone and terminology of the strings that ARE already translated in the same file — consistency matters more than literal accuracy.
70-
- For technical or brand terms (e.g. "Oinkoin Pro", "PIN", "CSV", "JSON") keep them untranslated.
71-
- If a string has no natural translation (e.g. it is already the correct word in the target language), it is fine to leave the value equal to the key — but note this in your report.
72-
- Process the **whole file** in one pass; do not ask for confirmation before each string.
73-
74-
## Exceptions
75-
76-
For British english use en-GB.json - in this case, key and value will most of case matches. Consider all the strings as already translated and skip it.
170+
- Process the **entire discovery list** in one invocation; do not stop to ask for confirmation.
171+
- `en-GB.json` is always skipped.

0 commit comments

Comments
 (0)