glotfile 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Glotfile</title>
7
- <script type="module" crossorigin src="/assets/index-C601vTV2.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-DNjcY2ek.css">
7
+ <script type="module" crossorigin src="/assets/index-DtQaiBsM.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-Cgnutw-J.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glotfile",
3
- "version": "0.7.3",
3
+ "version": "0.8.0",
4
4
  "description": "Local-first, git-native translation management.",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/SKILL.md CHANGED
@@ -25,8 +25,10 @@ To make a change:
25
25
 
26
26
  **Exception — Angular (`angular-xliff`):** source strings live in the code and
27
27
  `ng extract-i18n` generates `messages.xlf`; glotfile owns only the translations. New
28
- keys cannot be added in glotfile (trans-unit ids are content hashes) see "Angular
29
- projects" in `references/workflows.md` for the extract import translate → export loop.
28
+ keys cannot be added in glotfile (trans-unit ids are content hashes). After the first
29
+ `import`, resync with `glotfile sync` (never `import --force` it discards glossary and
30
+ context) — see "Angular projects" in `references/workflows.md` for the
31
+ extract → sync → translate → export loop.
30
32
 
31
33
  ## Before you touch anything: discover the project's actual config
32
34
 
@@ -64,6 +64,22 @@ flat i18next `<lng>.json` files look like vue-i18n, so they need an explicit
64
64
  - `--cldr` — expand CLDR plural forms.
65
65
  - `--force` — overwrite an existing `glotfile.json`.
66
66
 
67
+ ## sync
68
+ `glotfile sync [--format <name>] [--source <dir>] [--source-locale <code>] [--locales <list>] [--cldr] [--prune] [--dry-run]`
69
+ — re-read the locale files and **merge** them into the existing catalog. Use this to pull
70
+ re-extracted strings in without losing glotfile-owned data (the resync counterpart to the
71
+ one-time `import`). Format is auto-detected if omitted.
72
+ - New keys are added; a changed source value bumps the key and flips its translations to
73
+ `needs-review` (their text is kept); empty target locales are filled from any non-empty
74
+ incoming translation (existing translations are never overwritten).
75
+ - Glossary, key context/notes/descriptions, config, and translations are preserved.
76
+ - Removed keys (present locally, gone from the import) are **reported only** — pass
77
+ `--prune` to delete them.
78
+ - `--dry-run` prints the changeset (added / source-changed / adopted / removed) and writes
79
+ nothing.
80
+ - For Angular, `sync` also rebuilds `.glotfile/usage.json` from the source locations in
81
+ `messages.xlf`.
82
+
67
83
  ## build-context
68
84
  `glotfile build-context [--all] [--key <glob>] [--limit <n>] [--since <date>]` —
69
85
  AI-generate per-key context (where/how a string is used) to improve translation quality.
@@ -71,13 +87,17 @@ AI-generate per-key context (where/how a string is used) to improve translation
71
87
 
72
88
  ## scan
73
89
  `glotfile scan` — index the codebase's references to translation keys, writing
74
- `.glotfile/usage.json`. Feeds `build-context` and `prune --unused`.
90
+ `.glotfile/usage.json`. Feeds `build-context` and `prune --unused`. For Angular
91
+ (`angular-xliff`), the regex scanner can't see content-hash ids, so `scan` instead rebuilds
92
+ the index from the source locations recorded in `messages.xlf`.
75
93
 
76
94
  ## prune
77
95
  `glotfile prune (--empty-source | --unused) [--write]` — remove keys. **Dry-run (lists
78
96
  only) unless `--write` is given.**
79
97
  - `--empty-source` — keys whose source value is empty.
80
98
  - `--unused` — keys with no code reference (runs a scan first so the result is current).
99
+ For Angular, "unused" is computed from a fresh extraction (keys gone from `messages.xlf`),
100
+ so run `ng extract-i18n` before pruning.
81
101
 
82
102
  ## split
83
103
  `glotfile split` — convert a single `glotfile.json` into a `glotfile/` directory
@@ -58,18 +58,38 @@ generates `messages.xlf` (trans-unit ids are content hashes), so you cannot add
58
58
  editing glotfile — add the string in the template/`$localize` and re-extract. Glotfile
59
59
  owns the *translations*, not the source catalog:
60
60
 
61
+ **First time:** `glotfile import --format angular-xliff` to create `glotfile.json` from
62
+ `messages.xlf`.
63
+
64
+ **Every time after that, resync — don't re-import:**
65
+
61
66
  1. Mark strings in code (`i18n`/`i18n-<attr>` attributes, `$localize` tagged templates).
62
67
  2. `ng extract-i18n` (check `angular.json`/package scripts for the configured output
63
68
  path) to regenerate `messages.xlf`.
64
- 3. `glotfile import --format angular-xliff --force` to pull the new source strings in.
65
- Existing translations survive: they're read back from `messages.<locale>.xlf`, and
66
- exported `state="new"` placeholder targets are ignored, not treated as translations.
67
- ⚠️ `--force` rebuilds `glotfile.json`, so glossary entries, key context, and config
68
- edits made since the last import are lost re-apply them (or commit first and diff).
69
+ 3. `glotfile sync --dry-run` to preview the changeset (added / source-changed / removed),
70
+ then `glotfile sync` to apply. `sync` **merges** into the existing catalog: new strings
71
+ are added, edited source text bumps the key and flags its translations `needs-review`,
72
+ and crucially your glossary, key context/notes, descriptions, and existing
73
+ translations are preserved (unlike `import --force`, which rebuilds the file and loses
74
+ them). Removed keys are only reported; add `--prune` to delete them once you've
75
+ confirmed they're real deletions and not hash churn (see below).
69
76
  4. `glotfile translate` to fill the missing locales, then `glotfile export`. Export
70
77
  writes only `messages.<locale>.xlf` files (`skipSourceLocale`); it never touches
71
78
  `messages.xlf` — that file belongs to the Angular extractor.
72
79
 
80
+ **Hash churn — why `--prune` needs care.** trans-unit ids are content hashes of the
81
+ source text, so editing an English string produces a *new* id (the old one disappears).
82
+ `sync` sees that as one removed key + one added key, and the old key's translations and
83
+ context don't carry over to the new id. Prefer custom stable ids (`i18n="@@myId"`) where
84
+ churn matters: then a source edit is an in-place `source-changed`, keeping context and
85
+ flagging translations for re-check. Review `sync --dry-run` before `--prune`.
86
+
87
+ **Scan / unused for Angular.** The regex code scanner can't find hashed keys, so `glotfile
88
+ scan` rebuilds the usage index from the source locations Angular records in `messages.xlf`
89
+ (the UI "used in" tree works from these). `prune --unused` is driven by re-extraction —
90
+ a key absent from a fresh `messages.xlf` is the authoritative "unused" signal — so run
91
+ `ng extract-i18n` before pruning.
92
+
73
93
  Markup placeholders (`<x id="START_TAG_STRONG"/>` …) appear in glotfile values as
74
94
  `{START_TAG_STRONG}`-style tokens with their original attributes kept in the key's
75
95
  `placeholders` metadata; keep the tokens intact in translations and export reproduces