@contentrain/skills 0.1.1 → 0.2.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/README.md +65 -60
- package/dist/index.cjs +65 -1
- package/dist/index.d.cts +50 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +50 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +65 -2
- package/dist/index.mjs.map +1 -1
- package/frameworks/nuxt.md +26 -1
- package/package.json +3 -1
- package/skills/contentrain/SKILL.md +149 -0
- package/skills/contentrain/references/architecture.md +212 -0
- package/skills/contentrain/references/content-formats.md +279 -0
- package/skills/contentrain/references/i18n.md +298 -0
- package/skills/contentrain/references/mcp-pipelines.md +192 -0
- package/skills/contentrain/references/mcp-tools.md +308 -0
- package/skills/contentrain/references/model-kinds.md +330 -0
- package/skills/contentrain/references/schema-types.md +177 -0
- package/skills/contentrain/references/security.md +146 -0
- package/skills/contentrain/references/workflow.md +267 -0
- package/skills/contentrain-bulk/SKILL.md +99 -0
- package/skills/contentrain-content/SKILL.md +162 -0
- package/skills/contentrain-diff/SKILL.md +62 -0
- package/skills/contentrain-doctor/SKILL.md +62 -0
- package/skills/contentrain-generate/SKILL.md +183 -0
- package/skills/contentrain-generate/references/generated-client.md +198 -0
- package/skills/contentrain-init/SKILL.md +99 -0
- package/skills/contentrain-model/SKILL.md +141 -0
- package/skills/contentrain-normalize/SKILL.md +185 -0
- package/skills/contentrain-normalize/references/extraction.md +164 -0
- package/skills/contentrain-normalize/references/reuse.md +146 -0
- package/skills/contentrain-normalize/references/what-is-content.md +115 -0
- package/skills/contentrain-quality/SKILL.md +180 -0
- package/skills/contentrain-quality/references/accessibility.md +160 -0
- package/skills/contentrain-quality/references/content-quality.md +299 -0
- package/skills/contentrain-quality/references/media.md +170 -0
- package/skills/contentrain-quality/references/seo.md +229 -0
- package/skills/contentrain-review/SKILL.md +170 -0
- package/skills/contentrain-sdk/SKILL.md +145 -0
- package/skills/contentrain-sdk/references/bundler-config.md +135 -0
- package/skills/contentrain-serve/SKILL.md +96 -0
- package/skills/contentrain-translate/SKILL.md +180 -0
- package/skills/contentrain-validate-fix/SKILL.md +92 -0
- package/workflows/contentrain-content.md +1 -1
- package/workflows/contentrain-generate.md +5 -5
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contentrain-translate
|
|
3
|
+
description: "Translate Contentrain content across supported locales. Use when adding translations, localizing content, or managing multi-language entries."
|
|
4
|
+
metadata:
|
|
5
|
+
author: Contentrain
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Skill: Translate Content to a New Locale
|
|
10
|
+
|
|
11
|
+
> Translate existing content entries to a target locale, following i18n quality rules.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
The user wants to translate content, add a new language, or says something like "translate to Turkish", "add German locale", "create French translations", "fill in missing translations", "localize".
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Steps
|
|
22
|
+
|
|
23
|
+
### 1. Check Project State
|
|
24
|
+
|
|
25
|
+
Call `contentrain_status` to understand:
|
|
26
|
+
|
|
27
|
+
- Supported locales (from `config.json` → `locales.supported`).
|
|
28
|
+
- Source locale (from `config.json` → `locales.source`).
|
|
29
|
+
- Available models and their i18n status.
|
|
30
|
+
- Any pending changes or validation errors.
|
|
31
|
+
|
|
32
|
+
### 2. Determine Target Locale
|
|
33
|
+
|
|
34
|
+
If the user specified a locale, use it. Otherwise:
|
|
35
|
+
|
|
36
|
+
- Ask which locale to translate to.
|
|
37
|
+
- If the target locale is not in `locales.supported`, inform the user it needs to be added to the configuration first.
|
|
38
|
+
|
|
39
|
+
### 3. Select Models to Translate
|
|
40
|
+
|
|
41
|
+
Identify which models need translation:
|
|
42
|
+
|
|
43
|
+
- List all models with `i18n: true`.
|
|
44
|
+
- For each model, call `contentrain_content_list(model: "<modelId>", locale: "<sourceLocale>")` to get the source content.
|
|
45
|
+
- Check which models already have entries in the target locale by calling `contentrain_content_list(model: "<modelId>", locale: "<targetLocale>")`.
|
|
46
|
+
- Report the translation gap: how many entries exist in the source locale but not the target.
|
|
47
|
+
|
|
48
|
+
Ask the user which models to translate, or offer to translate all models with missing entries.
|
|
49
|
+
|
|
50
|
+
### 4. Load Vocabulary
|
|
51
|
+
|
|
52
|
+
Read `.contentrain/vocabulary.json` for canonical term translations. All vocabulary-defined terms must use the exact translation specified for the target locale — do not create alternative translations.
|
|
53
|
+
|
|
54
|
+
### 5. Translate Following i18n Rules
|
|
55
|
+
|
|
56
|
+
Apply the rules from `i18n-quality.md` during translation:
|
|
57
|
+
|
|
58
|
+
#### Translation Quality
|
|
59
|
+
|
|
60
|
+
- Translate meaning, not words. Produce idiomatic text in the target language.
|
|
61
|
+
- Match the sentence structure of the target language, not the source.
|
|
62
|
+
- Preserve the tone: if the source is casual, the translation must be casual. If formal, stay formal.
|
|
63
|
+
- Fix any machine-translation artifacts: literal translations, incorrect gender agreement, wrong register.
|
|
64
|
+
|
|
65
|
+
#### Vocabulary Alignment
|
|
66
|
+
|
|
67
|
+
- Check `.contentrain/vocabulary.json` for approved translations of terms in the target locale.
|
|
68
|
+
- Keep technical terms in their original form if no widely accepted translation exists (API, SDK, CLI, URL).
|
|
69
|
+
- Use brand terms exactly as specified per locale in the vocabulary.
|
|
70
|
+
- Do not alternate between synonyms — use the same translation for repeated terms throughout.
|
|
71
|
+
|
|
72
|
+
#### Cultural Adaptation
|
|
73
|
+
|
|
74
|
+
- Adapt idioms, metaphors, and culturally specific references. Do not translate literally when a cultural equivalent exists.
|
|
75
|
+
- Use locale-appropriate date formats, number formats, and units of measurement.
|
|
76
|
+
- Replace culturally specific references with locale-appropriate equivalents.
|
|
77
|
+
- Avoid idioms that do not translate — use target-language equivalents.
|
|
78
|
+
|
|
79
|
+
#### String Length Awareness
|
|
80
|
+
|
|
81
|
+
- Check field `max` constraints in the model definition.
|
|
82
|
+
- Account for expansion ratios: German +30-40%, French +15-25%, Chinese -30-50%.
|
|
83
|
+
- If a translation exceeds the field limit, rewrite it shorter. Never truncate mid-word.
|
|
84
|
+
- Pay special attention to UI strings (button labels, menu items) with tight space constraints.
|
|
85
|
+
- Flag any fields that hit `max` constraints.
|
|
86
|
+
|
|
87
|
+
#### Pluralization
|
|
88
|
+
|
|
89
|
+
- Use correct CLDR plural categories for the target language.
|
|
90
|
+
- English: `one`, `other`. German: `one`, `other`. Russian: `one`, `few`, `many`, `other`. Arabic: all six categories.
|
|
91
|
+
|
|
92
|
+
#### Preserve Non-Translatable Content
|
|
93
|
+
|
|
94
|
+
- Keep relation IDs, slugs, URLs, image paths, and code snippets unchanged — only translate human-readable text.
|
|
95
|
+
- Preserve markdown structure, HTML tags, line breaks, and whitespace patterns from the source.
|
|
96
|
+
- Entry IDs (object-map keys) remain the same across locales.
|
|
97
|
+
|
|
98
|
+
### 6. Kind-Specific Rules
|
|
99
|
+
|
|
100
|
+
- **singleton:** Translate all string/text/markdown/richtext fields.
|
|
101
|
+
- **collection:** Translate each entry's fields. Use the same entry IDs across locales.
|
|
102
|
+
- **document:** Translate frontmatter fields and markdown body. Slug may stay the same or be localized (ask the user).
|
|
103
|
+
- **dictionary:** Translate all values. Keys remain identical across locales (e.g., `"auth.login"` key stays the same, value changes).
|
|
104
|
+
|
|
105
|
+
### 7. Present Translations for Review
|
|
106
|
+
|
|
107
|
+
Show the user a side-by-side comparison:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Model: hero (singleton)
|
|
111
|
+
Field: title
|
|
112
|
+
en: "Build faster with AI"
|
|
113
|
+
tr: "AI ile daha hizli gelistirin"
|
|
114
|
+
|
|
115
|
+
Field: description
|
|
116
|
+
en: "Ship content-driven apps in minutes"
|
|
117
|
+
tr: "Icerik odakli uygulamalari dakikalar icinde yayinlayin"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Wait for user approval. The user may request adjustments to tone, phrasing, or terminology.
|
|
121
|
+
|
|
122
|
+
### 7.5. Bulk Copy for New Locales
|
|
123
|
+
|
|
124
|
+
When translating a model to a brand-new locale, use `copy_locale` to bootstrap the target locale with source content before translating:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
contentrain_bulk({ operation: "copy_locale", model: "<model-id>", source_locale: "en", target_locale: "<target>" })
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This creates target locale files with the source content as a starting point. Then translate each entry's values in-place — keys and entry IDs remain identical.
|
|
131
|
+
|
|
132
|
+
After all translations are saved, re-generate the SDK client so the application picks up the new locale data:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npx contentrain generate
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 8. Save Translations
|
|
139
|
+
|
|
140
|
+
After approval, call `contentrain_content_save` for each model and target locale:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
contentrain_content_save(model: "<model-id>", entries: [
|
|
144
|
+
{ id: "<same-id>", locale: "<target-locale>", data: { ...translatedFields } }
|
|
145
|
+
])
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Use the same `id` (for collections) or `slug` (for documents) as the source entry to maintain the cross-locale link. Batch all entries for a model in one call.
|
|
149
|
+
|
|
150
|
+
### 9. Validate
|
|
151
|
+
|
|
152
|
+
Call `contentrain_validate` to verify:
|
|
153
|
+
|
|
154
|
+
- i18n completeness — all source locale keys exist in the target locale.
|
|
155
|
+
- Schema compliance — translated values respect field constraints (`min`, `max`, `pattern`).
|
|
156
|
+
- Vocabulary alignment — vocabulary terms match their canonical translations.
|
|
157
|
+
- Referential integrity — relation fields are unchanged and still valid.
|
|
158
|
+
|
|
159
|
+
If validation fails, fix issues and re-save.
|
|
160
|
+
|
|
161
|
+
### 10. Submit
|
|
162
|
+
|
|
163
|
+
Call `contentrain_submit` to commit the translations:
|
|
164
|
+
|
|
165
|
+
- Branch: `contentrain/content/{model}/{targetLocale}/{timestamp}`.
|
|
166
|
+
- Each locale can be submitted independently.
|
|
167
|
+
|
|
168
|
+
### 11. Final Summary
|
|
169
|
+
|
|
170
|
+
Report to the user:
|
|
171
|
+
|
|
172
|
+
- Models translated: X.
|
|
173
|
+
- Entries translated: X.
|
|
174
|
+
- Target locale(s): X.
|
|
175
|
+
- Vocabulary terms applied: X.
|
|
176
|
+
- Any fields that hit `max` constraints (flagged for review).
|
|
177
|
+
- Validation result.
|
|
178
|
+
- Submission status.
|
|
179
|
+
- Reminder to review translations for nuance that automated checks cannot catch.
|
|
180
|
+
- Suggestion: run `/contentrain-review` to verify overall i18n coverage.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contentrain-validate-fix
|
|
3
|
+
description: "Validate Contentrain content against model schemas and auto-fix structural issues. Use when checking content validity or fixing validation errors."
|
|
4
|
+
metadata:
|
|
5
|
+
author: Contentrain
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Skill: Validate and Fix Content Issues
|
|
10
|
+
|
|
11
|
+
> Diagnose validation failures, apply safe fixes, and re-check the project.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
Use this when:
|
|
18
|
+
|
|
19
|
+
- validation reports errors or warnings
|
|
20
|
+
- the user asks to fix schema/content issues
|
|
21
|
+
- a write operation succeeded but the project still needs verification
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
### 1. Run Validation
|
|
28
|
+
|
|
29
|
+
Call `contentrain_validate` first.
|
|
30
|
+
|
|
31
|
+
Group results into:
|
|
32
|
+
|
|
33
|
+
- schema/type errors
|
|
34
|
+
- missing required fields
|
|
35
|
+
- relation integrity problems
|
|
36
|
+
- locale completeness issues
|
|
37
|
+
- canonical format warnings
|
|
38
|
+
|
|
39
|
+
### 2. Decide Auto-fix vs Manual Fix
|
|
40
|
+
|
|
41
|
+
Auto-fix candidates:
|
|
42
|
+
|
|
43
|
+
- canonical formatting
|
|
44
|
+
- orphan metadata cleanup
|
|
45
|
+
- structural housekeeping reported by the validator
|
|
46
|
+
|
|
47
|
+
Manual fix candidates:
|
|
48
|
+
|
|
49
|
+
- missing required content
|
|
50
|
+
- wrong field values
|
|
51
|
+
- broken relations
|
|
52
|
+
- incorrect slugs/IDs
|
|
53
|
+
|
|
54
|
+
### 3. Use Auto-fix Carefully
|
|
55
|
+
|
|
56
|
+
If the issues are structural, run:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"fix": true
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
After that, validate again.
|
|
65
|
+
|
|
66
|
+
### 4. Fix Semantic Errors
|
|
67
|
+
|
|
68
|
+
For real content or schema issues:
|
|
69
|
+
|
|
70
|
+
- inspect the model with `contentrain_describe`
|
|
71
|
+
- patch content with `contentrain_content_save`
|
|
72
|
+
- patch schema with `contentrain_model_save`
|
|
73
|
+
|
|
74
|
+
Do not claim the project is valid until validation is rerun.
|
|
75
|
+
|
|
76
|
+
### 5. Re-run Validation
|
|
77
|
+
|
|
78
|
+
Call `contentrain_validate` again and compare:
|
|
79
|
+
|
|
80
|
+
- errors reduced to zero
|
|
81
|
+
- remaining warnings acknowledged
|
|
82
|
+
|
|
83
|
+
### 6. Submit or Recommend Review
|
|
84
|
+
|
|
85
|
+
If validation is clean:
|
|
86
|
+
|
|
87
|
+
- call `contentrain_submit` when pending review branches exist
|
|
88
|
+
|
|
89
|
+
If validation still fails:
|
|
90
|
+
|
|
91
|
+
- summarize remaining blockers precisely
|
|
92
|
+
- tell the user which model/entry needs manual attention
|
|
@@ -102,7 +102,7 @@ contentrain_content_save({
|
|
|
102
102
|
- **dictionary:** `{ "locale": "en", "data": { "auth.login": "Log In", "auth.logout": "Log Out" } }` -- flat key-value pairs, no `id` or `slug`.
|
|
103
103
|
|
|
104
104
|
**Critical rules:**
|
|
105
|
-
- NEVER include system fields (`status`, `source`, `updated_by`, `
|
|
105
|
+
- NEVER include system fields (`status`, `source`, `updated_by`, `approved_by`) in `data`. These are managed in meta files, not content. Temporal data (created/updated timestamps) comes from git history.
|
|
106
106
|
- Prefer batch mode -- send multiple entries in a single call when possible.
|
|
107
107
|
- Locale defaults to the project's default locale if omitted, but explicit locale is recommended.
|
|
108
108
|
|
|
@@ -96,7 +96,7 @@ Ensure `tsconfig.json` does not block the generated client:
|
|
|
96
96
|
- `rootDir` or `include` should not exclude `.contentrain/client/`.
|
|
97
97
|
- If using `moduleResolution: "bundler"` or `"node16"`, subpath imports resolve natively.
|
|
98
98
|
|
|
99
|
-
###
|
|
99
|
+
### 6. Configure Bundler Alias
|
|
100
100
|
|
|
101
101
|
The `#contentrain` subpath import works natively in Node.js 22+ but **does NOT resolve in browser bundlers**. If the project uses a bundler, configure an alias so `#contentrain` resolves to the generated client.
|
|
102
102
|
|
|
@@ -188,7 +188,7 @@ module.exports = {
|
|
|
188
188
|
|
|
189
189
|
No alias needed. Node.js 22+ resolves `#contentrain` from `package.json` imports natively.
|
|
190
190
|
|
|
191
|
-
###
|
|
191
|
+
### 7. Verify Imports Work
|
|
192
192
|
|
|
193
193
|
Run a quick verification that the imports resolve correctly.
|
|
194
194
|
|
|
@@ -222,7 +222,7 @@ If verification fails, check:
|
|
|
222
222
|
- The `.contentrain/client/` directory was generated successfully.
|
|
223
223
|
- The bundler alias is configured (see Step 5.5) for browser projects.
|
|
224
224
|
|
|
225
|
-
###
|
|
225
|
+
### 8. Show Usage Examples
|
|
226
226
|
|
|
227
227
|
Based on the detected stack and available models, show relevant examples using actual model IDs and field names from the project — not generic placeholders.
|
|
228
228
|
|
|
@@ -319,7 +319,7 @@ const article = document('blog-article').locale('en').include('author').bySlug('
|
|
|
319
319
|
| Expo / RN | `const hero = singleton('hero').locale('en').get()` | `metro.config.js` resolver (Step 5.5) |
|
|
320
320
|
| Node.js / SSR | Direct import — no alias needed | Native subpath imports |
|
|
321
321
|
|
|
322
|
-
###
|
|
322
|
+
### 9. Offer Watch Mode
|
|
323
323
|
|
|
324
324
|
Suggest setting up watch mode for development:
|
|
325
325
|
|
|
@@ -339,7 +339,7 @@ For convenience, suggest adding a script to `package.json`:
|
|
|
339
339
|
}
|
|
340
340
|
```
|
|
341
341
|
|
|
342
|
-
###
|
|
342
|
+
### 10. Final Summary
|
|
343
343
|
|
|
344
344
|
Report to the user:
|
|
345
345
|
|