@shipi18n/cli 2.8.0 → 2.9.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @shipi18n/cli
2
2
 
3
+ ## 2.9.0
4
+
5
+ - New: `check` now supports **Android `strings.xml`, gettext `.po`/`.pot`, and XLIFF 1.2/2.0** on top
6
+ of JSON, YAML, Flutter `.arb` and Apple `.xcstrings` — auto-detected from the input path (via core
7
+ 2.9.0). The structural pass still needs no API key.
8
+
9
+ ## 2.8.1
10
+
11
+ - Security (hardening): pulls core 2.8.1 (translator prompt-injection guardrail + recursion depth
12
+ bound). The `--semantic-cache` help now notes the verdict cache is a per-machine cost cache that
13
+ should be gitignored — a committed cache is untrusted and could suppress real findings.
14
+
3
15
  ## 2.8.0
4
16
 
5
17
  - New: ICU MessageFormat checks via core 2.8.0 — `plural-category` (missing CLDR plural categories,
package/README.md CHANGED
@@ -91,7 +91,8 @@ npx @shipi18n/cli check ./locales --source en
91
91
  ```
92
92
 
93
93
  It detects both common layouts (`locales/en.json` and `locales/en/<ns>.json`), plus Flutter ARB
94
- directories and Apple String Catalogs (`shipi18n check Localizable.xcstrings`).
94
+ directories, Apple String Catalogs (`shipi18n check Localizable.xcstrings`), Android `res/values-*/`
95
+ `strings.xml` trees, gettext `.po`/`.pot`, and XLIFF (`.xlf`/`.xliff`, 1.2 and 2.0).
95
96
 
96
97
  **What it catches:** missing and orphaned keys · dropped or invented placeholders (`{{name}}`,
97
98
  `{count}`, `%s`, `%1$s`, `%@`, `%lld`, `$t(...)`, `%{name}`, HTML tags) · collapsed vue-i18n pipe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipi18n/cli",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "description": "Catch broken translations before you ship: dropped placeholders, missing keys, collapsed plurals and — with your own LLM key — mistranslations the structure checks cannot see. CI-ready (SARIF, JUnit, exit codes). Translates too.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -49,7 +49,7 @@
49
49
  "chalk": "^5.3.0",
50
50
  "commander": "^12.0.0",
51
51
  "ora": "^8.0.1",
52
- "@shipi18n/core": "^2.8.0"
52
+ "@shipi18n/core": "^2.9.0"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@anthropic-ai/sdk": ">=0.30.0",
@@ -7,8 +7,9 @@
7
7
  * pipeline can gate on it.
8
8
  *
9
9
  * Formats: plain JSON locale trees (flat `locales/<lang>.json` or nested
10
- * `locales/<lang>/<ns>.json`), Flutter ARB directories, and Apple String
11
- * Catalogs (`.xcstrings`). Reporters: human, json, sarif, junit.
10
+ * `locales/<lang>/<ns>.json`), YAML, Flutter ARB directories, Apple String
11
+ * Catalogs (`.xcstrings`), Android `strings.xml` trees, gettext `.po`/`.pot`,
12
+ * and XLIFF (`.xlf`/`.xliff`, 1.2 & 2.0). Reporters: human, json, sarif, junit.
12
13
  */
13
14
  import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'node:fs'
14
15
  import { resolve, dirname, join } from 'node:path'
@@ -68,7 +69,7 @@ export function checkCommand(program) {
68
69
  'OpenAI-compatible endpoint for the judge (Ollama, Gemini compat, ...). Needs -p openai; makes the key optional'
69
70
  )
70
71
  .option('--semantic-passes <n>', 'Judge passes for the majority vote', (v) => parseInt(v, 10), 3)
71
- .option('--semantic-cache <file>', 'Verdict cache path', '.shipi18n/semantic-cache.json')
72
+ .option('--semantic-cache <file>', 'Verdict cache path (per-machine cost cache; gitignore it — a committed cache is untrusted)', '.shipi18n/semantic-cache.json')
72
73
  .option('--locks <file>', 'Manual-translation lock file', DEFAULT_LOCKS_PATH)
73
74
  .option('--no-locks', 'Ignore manual-translation locks')
74
75
  .action(async (input = './locales', opts) => {