@contentrain/rules 0.2.0 → 0.3.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 +24 -51
- package/dist/index.cjs +2 -26
- package/dist/index.d.cts +2 -11
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -23
- package/dist/index.mjs.map +1 -1
- package/essential/contentrain-essentials.md +86 -0
- package/package.json +6 -9
- package/ide/claude-code/contentrain.md +0 -2984
- package/ide/claude-code/rules/contentrain-accessibility-rules.md +0 -155
- package/ide/claude-code/rules/contentrain-content-conventions.md +0 -314
- package/ide/claude-code/rules/contentrain-content-quality.md +0 -294
- package/ide/claude-code/rules/contentrain-i18n-quality.md +0 -293
- package/ide/claude-code/rules/contentrain-mcp-usage.md +0 -405
- package/ide/claude-code/rules/contentrain-media-rules.md +0 -165
- package/ide/claude-code/rules/contentrain-normalize-rules.md +0 -312
- package/ide/claude-code/rules/contentrain-schema-rules.md +0 -380
- package/ide/claude-code/rules/contentrain-security-rules.md +0 -141
- package/ide/claude-code/rules/contentrain-seo-rules.md +0 -224
- package/ide/claude-code/rules/contentrain-workflow-rules.md +0 -262
- package/ide/cursor/contentrain.cursorrules +0 -2959
- package/ide/cursor/rules/contentrain-accessibility-rules.mdc +0 -160
- package/ide/cursor/rules/contentrain-content-conventions.mdc +0 -319
- package/ide/cursor/rules/contentrain-content-quality.mdc +0 -299
- package/ide/cursor/rules/contentrain-i18n-quality.mdc +0 -298
- package/ide/cursor/rules/contentrain-mcp-usage.mdc +0 -410
- package/ide/cursor/rules/contentrain-media-rules.mdc +0 -170
- package/ide/cursor/rules/contentrain-normalize-rules.mdc +0 -317
- package/ide/cursor/rules/contentrain-schema-rules.mdc +0 -385
- package/ide/cursor/rules/contentrain-security-rules.mdc +0 -146
- package/ide/cursor/rules/contentrain-seo-rules.mdc +0 -229
- package/ide/cursor/rules/contentrain-workflow-rules.mdc +0 -267
- package/ide/generic/contentrain.md +0 -2984
- package/ide/windsurf/contentrain.windsurfrules +0 -2984
- package/ide/windsurf/rules/contentrain-accessibility-rules.md +0 -160
- package/ide/windsurf/rules/contentrain-content-conventions.md +0 -319
- package/ide/windsurf/rules/contentrain-content-quality.md +0 -299
- package/ide/windsurf/rules/contentrain-i18n-quality.md +0 -298
- package/ide/windsurf/rules/contentrain-mcp-usage.md +0 -410
- package/ide/windsurf/rules/contentrain-media-rules.md +0 -170
- package/ide/windsurf/rules/contentrain-normalize-rules.md +0 -317
- package/ide/windsurf/rules/contentrain-schema-rules.md +0 -385
- package/ide/windsurf/rules/contentrain-security-rules.md +0 -146
- package/ide/windsurf/rules/contentrain-seo-rules.md +0 -229
- package/ide/windsurf/rules/contentrain-workflow-rules.md +0 -267
- package/shared/accessibility-rules.md +0 -155
- package/shared/content-conventions.md +0 -314
- package/shared/content-quality.md +0 -294
- package/shared/i18n-quality.md +0 -293
- package/shared/mcp-usage.md +0 -405
- package/shared/media-rules.md +0 -165
- package/shared/normalize-rules.md +0 -312
- package/shared/schema-rules.md +0 -380
- package/shared/security-rules.md +0 -141
- package/shared/seo-rules.md +0 -224
- package/shared/workflow-rules.md +0 -262
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Accessibility Rules — Contentrain content governance
|
|
3
|
-
trigger: always_on
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Accessibility Rules
|
|
7
|
-
|
|
8
|
-
These rules are MANDATORY for all AI agents creating or editing content in Contentrain projects.
|
|
9
|
-
Violations will be flagged during validation. No exceptions unless explicitly overridden by `context.json` configuration.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Image Accessibility
|
|
14
|
-
|
|
15
|
-
1. Every `image` type field MUST have a corresponding alt text value. If the model defines an `image_alt` field, populate it. If not, include alt text guidance in the image field's `description` metadata.
|
|
16
|
-
|
|
17
|
-
2. Alt text MUST describe the image's **content and function**, not its appearance.
|
|
18
|
-
- GOOD: `"CEO Jane Doe speaking at the 2024 product launch"`
|
|
19
|
-
- BAD: `"A photo with blue tones and a person on stage"`
|
|
20
|
-
|
|
21
|
-
3. Decorative images (visual separators, background textures) MUST have alt text set to an empty string `""`. Never leave alt text undefined or null — explicitly set it to `""`.
|
|
22
|
-
|
|
23
|
-
4. Complex images (charts, infographics, diagrams) MUST have a short alt text summarizing the conclusion, plus a detailed description in an adjacent text field or in the body content.
|
|
24
|
-
- Example alt: `"Bar chart showing Q3 revenue grew 22% year-over-year"`
|
|
25
|
-
- Example adjacent text: full data table or written summary
|
|
26
|
-
|
|
27
|
-
5. Alt text MUST NOT exceed **125 characters**. Screen readers may truncate longer text.
|
|
28
|
-
|
|
29
|
-
6. Icon images used as interactive elements MUST have alt text describing the **action**, not the icon.
|
|
30
|
-
- GOOD: `"Search"`, `"Close menu"`, `"Open settings"`
|
|
31
|
-
- BAD: `"Magnifying glass icon"`, `"X icon"`
|
|
32
|
-
|
|
33
|
-
7. Do not begin alt text with "Image of" or "Photo of" — the screen reader already announces it as an image.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Language & Readability
|
|
38
|
-
|
|
39
|
-
1. Target a **grade 8-10 reading level** (Flesch-Kincaid) for general content.
|
|
40
|
-
|
|
41
|
-
2. Target **grade 6-8** for public-facing critical content: legal notices, safety information, error messages, onboarding flows.
|
|
42
|
-
|
|
43
|
-
3. Use plain language. Prefer common words over formal synonyms:
|
|
44
|
-
- "use" not "utilize"
|
|
45
|
-
- "start" not "commence"
|
|
46
|
-
- "help" not "facilitate"
|
|
47
|
-
- "buy" not "purchase"
|
|
48
|
-
- "end" not "terminate"
|
|
49
|
-
|
|
50
|
-
4. Define every acronym and abbreviation on first use: `"Content Management System (CMS)"`. After the first definition, use the acronym freely.
|
|
51
|
-
|
|
52
|
-
5. Do not use jargon unless the content targets a technical audience. Check `context.json > tone` to determine the audience. When `tone` is `"technical"`, domain-specific terms are acceptable without definitions.
|
|
53
|
-
|
|
54
|
-
6. Keep sentences short: **15-20 words average**. Break long sentences at natural clause boundaries.
|
|
55
|
-
|
|
56
|
-
7. Keep paragraphs short: **3-5 sentences maximum**. Use line breaks between paragraphs.
|
|
57
|
-
|
|
58
|
-
8. Use active voice. Passive voice is acceptable only when the actor is unknown or irrelevant.
|
|
59
|
-
- GOOD: `"The system saves your changes automatically."`
|
|
60
|
-
- BAD: `"Your changes are saved automatically by the system."`
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Link Text
|
|
65
|
-
|
|
66
|
-
1. Link text MUST be descriptive and self-explanatory. It must make sense **out of context** because screen readers present links in an isolated list.
|
|
67
|
-
- GOOD: `"Download the 2024 Annual Report"`
|
|
68
|
-
- BAD: `"Click here"`
|
|
69
|
-
|
|
70
|
-
2. NEVER use these as standalone link text: `"click here"`, `"read more"`, `"learn more"`, `"here"`, `"link"`, `"this"`.
|
|
71
|
-
|
|
72
|
-
3. For file downloads, include the file type and size in the link text:
|
|
73
|
-
- `"Download the Q3 Budget (PDF, 2.4 MB)"`
|
|
74
|
-
|
|
75
|
-
4. Do not use the raw URL as link text unless the content is specifically listing URLs.
|
|
76
|
-
|
|
77
|
-
5. Keep link text concise — describe the destination or action in 2-8 words.
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Heading Semantics
|
|
82
|
-
|
|
83
|
-
1. Headings MUST describe the content of their section. Never use headings purely for visual styling (font size, bold).
|
|
84
|
-
|
|
85
|
-
2. Heading levels MUST reflect **document hierarchy**:
|
|
86
|
-
- `h2` for top-level sections within the page
|
|
87
|
-
- `h3` for subsections of an `h2`
|
|
88
|
-
- `h4` for subsections of an `h3`
|
|
89
|
-
- Never skip levels (e.g., `h2` directly to `h4`)
|
|
90
|
-
|
|
91
|
-
3. Every distinct content section SHOULD have a heading.
|
|
92
|
-
|
|
93
|
-
4. Headings MUST NOT be empty or contain only whitespace.
|
|
94
|
-
|
|
95
|
-
5. Do not duplicate heading text within the same page unless sections are genuinely distinct (e.g., "Overview" under two different parent headings is acceptable).
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Content Structure
|
|
100
|
-
|
|
101
|
-
1. Use **semantic markup** appropriate to the content type:
|
|
102
|
-
- Unordered lists (`ul`) for items without sequence
|
|
103
|
-
- Ordered lists (`ol`) for steps or ranked items
|
|
104
|
-
- Headings for section titles
|
|
105
|
-
- Paragraphs for body text
|
|
106
|
-
- Blockquotes for quoted material
|
|
107
|
-
|
|
108
|
-
2. Tables MUST include a header row or header column. Keep table structure simple — avoid merged cells and nested tables.
|
|
109
|
-
|
|
110
|
-
3. Provide a text alternative for every piece of non-text content (images, charts, embedded media).
|
|
111
|
-
|
|
112
|
-
4. Sequential content (steps, instructions, timelines) MUST follow logical reading order. Do not rely on CSS or layout to reorder content.
|
|
113
|
-
|
|
114
|
-
5. Lists MUST have at least two items. A single-item list should be rewritten as a paragraph or inline text.
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Color & Visual References
|
|
119
|
-
|
|
120
|
-
1. NEVER use color alone to convey meaning.
|
|
121
|
-
- BAD: `"Required fields are highlighted in red."`
|
|
122
|
-
- GOOD: `"Required fields are marked with an asterisk (*)."`
|
|
123
|
-
|
|
124
|
-
2. Do not reference visual position in content text.
|
|
125
|
-
- BAD: `"Click the button on the right."`
|
|
126
|
-
- GOOD: `"Click the Submit button."`
|
|
127
|
-
|
|
128
|
-
3. Ensure all text content is meaningful without any visual context. Content must be understandable when read aloud or rendered in plain text.
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
## Error Messages & Forms
|
|
133
|
-
|
|
134
|
-
1. Error messages MUST identify **which field** has the error.
|
|
135
|
-
|
|
136
|
-
2. Error messages MUST describe **what the error is** and how to fix it.
|
|
137
|
-
- GOOD: `"Enter a valid email address (e.g., name@example.com)."`
|
|
138
|
-
- BAD: `"Invalid input."`
|
|
139
|
-
|
|
140
|
-
3. Use **positive framing** — tell the user what to do, not what they did wrong.
|
|
141
|
-
- GOOD: `"Enter a date in YYYY-MM-DD format."`
|
|
142
|
-
- BAD: `"Wrong date format."`
|
|
143
|
-
|
|
144
|
-
4. Group related form fields with descriptive labels. Every input field MUST have a label.
|
|
145
|
-
|
|
146
|
-
5. Do not use placeholder text as a substitute for labels.
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Multimedia
|
|
151
|
-
|
|
152
|
-
1. Video content MUST reference a transcript — either as inline content, a URL, or a relation to a document entry.
|
|
153
|
-
|
|
154
|
-
2. Audio content MUST have a text transcript available.
|
|
155
|
-
|
|
156
|
-
3. If content auto-plays, note this in metadata so the frontend can provide pause/stop controls. Auto-playing media with audio is strongly discouraged.
|
|
157
|
-
|
|
158
|
-
4. Time-based media (video, audio, animations) MUST include duration information when the model supports it.
|
|
159
|
-
|
|
160
|
-
5. Animated content (GIFs, auto-playing videos) should be flagged if longer than 5 seconds — provide a mechanism to pause.
|
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Content Conventions — Contentrain content governance
|
|
3
|
-
trigger: always_on
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Contentrain Content Conventions
|
|
7
|
-
|
|
8
|
-
> These rules govern how content is structured, stored, and serialized in the `.contentrain/` directory. Follow them exactly when creating or modifying content through MCP tools.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## 1. Directory Structure
|
|
13
|
-
|
|
14
|
-
All Contentrain data lives under the `.contentrain/` directory at the project root. Understand every subdirectory's purpose before reading or writing.
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
.contentrain/
|
|
18
|
-
config.json # Project configuration (stack, workflow, locales, domains)
|
|
19
|
-
vocabulary.json # Canonical terms for consistent terminology
|
|
20
|
-
context.json # Project intelligence — MCP writes after every write op, agents READ ONLY
|
|
21
|
-
assets.json # Media asset registry
|
|
22
|
-
models/
|
|
23
|
-
{model-id}.json # Model definitions (one file per model)
|
|
24
|
-
content/
|
|
25
|
-
{domain}/
|
|
26
|
-
{model-id}/
|
|
27
|
-
en.json # Content per locale (i18n: true)
|
|
28
|
-
tr.json
|
|
29
|
-
data.json # Content without locale (i18n: false)
|
|
30
|
-
{slug}/ # Document kind only
|
|
31
|
-
en.md
|
|
32
|
-
tr.md
|
|
33
|
-
meta/
|
|
34
|
-
{model-id}/
|
|
35
|
-
{locale}.json # System-managed metadata
|
|
36
|
-
{slug}/ # Document kind only
|
|
37
|
-
{locale}.json
|
|
38
|
-
client/ # SDK generated client — auto-generated, NEVER edit
|
|
39
|
-
assets/ # Media files (images, videos, documents)
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Critical Boundaries
|
|
43
|
-
|
|
44
|
-
- **NEVER write to `.contentrain/meta/`** -- metadata is system-managed (status, source, updated_by, approved_by).
|
|
45
|
-
- **NEVER edit `.contentrain/client/`** -- this is auto-generated by `contentrain generate`.
|
|
46
|
-
- **NEVER edit `.contentrain/context.json`** -- MCP writes it; agents read it for project intelligence.
|
|
47
|
-
- **ALWAYS use MCP tools** to create/update content and models. Do not write JSON files directly.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## 2. config.json Structure
|
|
52
|
-
|
|
53
|
-
The project configuration file controls global behavior. It is created by `contentrain_init`.
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"version": 1,
|
|
58
|
-
"stack": "nuxt",
|
|
59
|
-
"workflow": "auto-merge",
|
|
60
|
-
"repository": {
|
|
61
|
-
"provider": "github",
|
|
62
|
-
"owner": "contentrain",
|
|
63
|
-
"name": "demo",
|
|
64
|
-
"default_branch": "main"
|
|
65
|
-
},
|
|
66
|
-
"locales": {
|
|
67
|
-
"default": "en",
|
|
68
|
-
"supported": ["en", "tr"]
|
|
69
|
-
},
|
|
70
|
-
"domains": ["blog", "marketing", "system"],
|
|
71
|
-
"assets_path": ".contentrain/assets",
|
|
72
|
-
"branchRetention": 30
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Field Reference
|
|
77
|
-
|
|
78
|
-
| Field | Type | Description |
|
|
79
|
-
|-------|------|-------------|
|
|
80
|
-
| `version` | `number` | Config schema version. Always `1`. |
|
|
81
|
-
| `stack` | `string` | Detected or set framework: `"nuxt"`, `"next"`, `"astro"`, `"sveltekit"`, `"react"`, `"node"` |
|
|
82
|
-
| `workflow` | `string` | `"auto-merge"` (solo dev) or `"review"` (team governance) |
|
|
83
|
-
| `repository` | `object` | Git remote info. Provider is always `"github"` in v1. |
|
|
84
|
-
| `locales.default` | `string` | Primary locale (ISO 639-1) |
|
|
85
|
-
| `locales.supported` | `string[]` | All locales including default |
|
|
86
|
-
| `domains` | `string[]` | Organizational groups for content (e.g., `"blog"`, `"marketing"`, `"system"`) |
|
|
87
|
-
| `assets_path` | `string` | Path for media files |
|
|
88
|
-
| `branchRetention` | `number` | Days to keep merged branches |
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## 3. Content File Formats by Model Kind
|
|
93
|
-
|
|
94
|
-
Each of the 4 model kinds has a distinct storage format. Know them precisely.
|
|
95
|
-
|
|
96
|
-
### 3.1 Singleton
|
|
97
|
-
|
|
98
|
-
One JSON object per locale file. No `id` field.
|
|
99
|
-
|
|
100
|
-
**Path:** `.contentrain/content/{domain}/{model-id}/{locale}.json`
|
|
101
|
-
|
|
102
|
-
```json
|
|
103
|
-
{
|
|
104
|
-
"cta": "Get Started",
|
|
105
|
-
"subtitle": "The modern content platform",
|
|
106
|
-
"title": "Build faster"
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Use for:** Hero sections, navigation, site config, form labels -- anything with exactly one instance per locale.
|
|
111
|
-
|
|
112
|
-
### 3.2 Collection
|
|
113
|
-
|
|
114
|
-
Object-map on disk: keys are entry IDs, sorted lexicographically. The `id` field is the key itself and is NOT stored inside the entry object.
|
|
115
|
-
|
|
116
|
-
**Path:** `.contentrain/content/{domain}/{model-id}/{locale}.json`
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"a1b2c3d4e5f6": {
|
|
121
|
-
"avatar": "assets/ahmet.jpg",
|
|
122
|
-
"name": "Ahmet",
|
|
123
|
-
"role": "CEO"
|
|
124
|
-
},
|
|
125
|
-
"f6e5d4c3b2a1": {
|
|
126
|
-
"avatar": "assets/jane.jpg",
|
|
127
|
-
"name": "Jane",
|
|
128
|
-
"role": "CTO"
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**MCP output format differs from storage:** MCP tools return collections as arrays with `id` injected:
|
|
134
|
-
|
|
135
|
-
```json
|
|
136
|
-
[
|
|
137
|
-
{ "id": "a1b2c3d4e5f6", "name": "Ahmet", "role": "CEO", "avatar": "assets/ahmet.jpg" },
|
|
138
|
-
{ "id": "f6e5d4c3b2a1", "name": "Jane", "role": "CTO", "avatar": "assets/jane.jpg" }
|
|
139
|
-
]
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
**Why object-map?**
|
|
143
|
-
- Sorted keys produce predictable diffs and minimize Git merge conflicts.
|
|
144
|
-
- No ID duplication -- key IS the ID.
|
|
145
|
-
- Consistent structure with metadata files.
|
|
146
|
-
|
|
147
|
-
### 3.3 Document
|
|
148
|
-
|
|
149
|
-
Markdown file with YAML-like frontmatter. One file per slug per locale.
|
|
150
|
-
|
|
151
|
-
**Path:** `.contentrain/content/{domain}/{model-id}/{slug}/{locale}.md`
|
|
152
|
-
|
|
153
|
-
```markdown
|
|
154
|
-
---
|
|
155
|
-
title: Getting Started
|
|
156
|
-
slug: getting-started
|
|
157
|
-
author: a1b2c3d4e5f6
|
|
158
|
-
tags: [tutorial, intro]
|
|
159
|
-
---
|
|
160
|
-
# Getting Started with Contentrain
|
|
161
|
-
|
|
162
|
-
Your markdown body content here...
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
**Use for:** Blog posts, documentation pages, changelogs -- long-form content with typed metadata.
|
|
166
|
-
|
|
167
|
-
### 3.4 Dictionary
|
|
168
|
-
|
|
169
|
-
Flat key-value JSON per locale. No `fields` in the model definition -- all values are strings.
|
|
170
|
-
|
|
171
|
-
**Path:** `.contentrain/content/{domain}/{model-id}/{locale}.json`
|
|
172
|
-
|
|
173
|
-
```json
|
|
174
|
-
{
|
|
175
|
-
"auth.expired": "Session expired",
|
|
176
|
-
"auth.failed": "Authentication failed",
|
|
177
|
-
"validation.required": "{field} is required"
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
**Use for:** Error messages, UI strings, i18n translation files, mobile app strings.
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## 4. Canonical Serialization Rules
|
|
186
|
-
|
|
187
|
-
ALL JSON files in `.contentrain/` MUST follow these rules for deterministic, git-friendly output:
|
|
188
|
-
|
|
189
|
-
1. **Keys sorted lexicographically** within every object (including nested objects).
|
|
190
|
-
2. **2-space indent** for all nesting levels.
|
|
191
|
-
3. **UTF-8 encoding** without BOM.
|
|
192
|
-
4. **Trailing newline** at end of file (single `\n` after closing brace/bracket).
|
|
193
|
-
5. **Omit null values** -- do not write `"field": null`.
|
|
194
|
-
6. **Omit default values** -- if `required` is `false`, do not include it. If `default` is `null`, do not include it.
|
|
195
|
-
7. **Field key order in content entries** follows the model definition insertion order for readability, but storage uses lexicographic sort for determinism.
|
|
196
|
-
|
|
197
|
-
### Why This Matters
|
|
198
|
-
|
|
199
|
-
- Deterministic output means identical data always produces identical files.
|
|
200
|
-
- Sorted keys prevent artificial Git diffs from key reordering.
|
|
201
|
-
- Clean diffs enable meaningful code review of content changes.
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## 5. System Fields
|
|
206
|
-
|
|
207
|
-
Several fields are managed by the platform. Agents MUST NOT set or modify them.
|
|
208
|
-
|
|
209
|
-
| Field | Where | Managed By |
|
|
210
|
-
|-------|-------|------------|
|
|
211
|
-
| `id` | Collection entry key | Auto-generated 12-char hex UUID |
|
|
212
|
-
| `slug` | Document directory name | Derived from content or set by agent via `slug` field |
|
|
213
|
-
| `createdAt` | Not stored | Derived from Git commit history |
|
|
214
|
-
| `updatedAt` | Not stored | Derived from Git commit history |
|
|
215
|
-
| `status` | `.contentrain/meta/` | Platform workflow engine |
|
|
216
|
-
| `source` | `.contentrain/meta/` | Set by MCP: `"agent"`, `"human"`, or `"import"` |
|
|
217
|
-
| `updated_by` | `.contentrain/meta/` | Set by MCP: agent name or user email |
|
|
218
|
-
| `approved_by` | `.contentrain/meta/` | Set by Studio on review approval |
|
|
219
|
-
|
|
220
|
-
**Rule:** When creating content via `contentrain_content_save`, provide only the content fields defined in the model. Do not include `id`, `createdAt`, `updatedAt`, `status`, or any metadata fields.
|
|
221
|
-
|
|
222
|
-
---
|
|
223
|
-
|
|
224
|
-
## 6. Localization Rules
|
|
225
|
-
|
|
226
|
-
| Rule | Detail |
|
|
227
|
-
|------|--------|
|
|
228
|
-
| `i18n: true` on model | Each locale gets its own file: `en.json`, `tr.json`, etc. |
|
|
229
|
-
| `i18n: false` on model | Single file: `data.json` (or `{slug}.md` for documents) |
|
|
230
|
-
| Locale code | ISO 639-1: `en`, `tr`, `de`, `fr`, `ja`, `ar` |
|
|
231
|
-
| ID/slug are locale-agnostic | The same entry ID or document slug is used across all locales |
|
|
232
|
-
| Entry parity (collections) | All locales MUST have the same set of entry IDs |
|
|
233
|
-
| Key parity (dictionaries) | All locales MUST have the same set of keys |
|
|
234
|
-
|
|
235
|
-
### Validation Checks
|
|
236
|
-
|
|
237
|
-
| Check | Severity | Example |
|
|
238
|
-
|-------|----------|---------|
|
|
239
|
-
| Missing locale file | Error | `hero: tr.json missing` |
|
|
240
|
-
| Collection entry ID mismatch | Error | `team-members: entry "member-2" missing in tr` |
|
|
241
|
-
| Dictionary key missing | Warning | `error-messages: tr missing 5 keys` |
|
|
242
|
-
| Document missing translation | Warning | `blog-post: "getting-started" has no tr translation` |
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
## 7. Vocabulary
|
|
247
|
-
|
|
248
|
-
The `vocabulary.json` file provides canonical terms for consistent content.
|
|
249
|
-
|
|
250
|
-
```json
|
|
251
|
-
{
|
|
252
|
-
"version": 1,
|
|
253
|
-
"terms": {
|
|
254
|
-
"email": { "en": "Email", "tr": "E-posta" },
|
|
255
|
-
"sign-up": { "en": "Sign Up", "tr": "Kayit Ol" }
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Rules
|
|
261
|
-
|
|
262
|
-
- **Check vocabulary FIRST** before writing any content. Use existing terms when they match.
|
|
263
|
-
- **Add new terms** to the vocabulary when creating content with reusable terminology.
|
|
264
|
-
- **Term keys** are kebab-case identifiers.
|
|
265
|
-
- **Each term** maps to locale-specific approved strings.
|
|
266
|
-
- Vocabulary ensures consistency across models, locales, and agent sessions.
|
|
267
|
-
|
|
268
|
-
---
|
|
269
|
-
|
|
270
|
-
## 8. context.json
|
|
271
|
-
|
|
272
|
-
MCP writes `context.json` after every write operation. It provides project intelligence for agents and Studio synchronization.
|
|
273
|
-
|
|
274
|
-
```json
|
|
275
|
-
{
|
|
276
|
-
"version": "1.0",
|
|
277
|
-
"lastOperation": {
|
|
278
|
-
"tool": "content_save",
|
|
279
|
-
"model": "blog-post",
|
|
280
|
-
"locale": "en",
|
|
281
|
-
"entries": ["a1b2c3d4e5f6"],
|
|
282
|
-
"timestamp": "2026-03-11T14:30:00Z",
|
|
283
|
-
"source": "mcp-local"
|
|
284
|
-
},
|
|
285
|
-
"stats": {
|
|
286
|
-
"models": 5,
|
|
287
|
-
"entries": 142,
|
|
288
|
-
"locales": ["en", "tr"],
|
|
289
|
-
"lastSync": "2026-03-11T14:30:00Z"
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### Rules
|
|
295
|
-
|
|
296
|
-
- **Read only** -- agents MUST NOT write to this file.
|
|
297
|
-
- **Use it for awareness** -- check last operation, entry counts, locale coverage.
|
|
298
|
-
- `source` values: `"mcp-local"` (IDE), `"mcp-studio"` (Studio server-side), `"studio-ui"` (Studio direct).
|
|
299
|
-
- Updated only on write operations (not reads).
|
|
300
|
-
- Git-tracked within `.contentrain/`.
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## 9. Assets
|
|
305
|
-
|
|
306
|
-
Media files are stored in the configured `assets_path`. The `assets.json` file tracks registered assets.
|
|
307
|
-
|
|
308
|
-
```json
|
|
309
|
-
[
|
|
310
|
-
{ "path": "assets/hero.webp", "type": "image/webp", "size": 245680, "alt": "Hero background" }
|
|
311
|
-
]
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Rules for Media References
|
|
315
|
-
|
|
316
|
-
- Use relative paths from the `.contentrain/` root in content fields.
|
|
317
|
-
- Media field types (`image`, `video`, `file`) store string path references.
|
|
318
|
-
- In v1, media fields are URL/path strings only. Upload and processing are out of scope.
|
|
319
|
-
- Always provide `alt` text for images when the information is available.
|