@contentrain/rules 0.1.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/LICENSE +21 -0
- package/README.md +128 -0
- package/context/context-bridge.md +241 -0
- package/context/templates/astro.context.json +74 -0
- package/context/templates/next.context.json +74 -0
- package/context/templates/nuxt.context.json +74 -0
- package/context/templates/sveltekit.context.json +74 -0
- package/dist/index.cjs +98 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +27 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +92 -0
- package/dist/index.mjs.map +1 -0
- package/ide/claude-code/contentrain.md +2984 -0
- package/ide/cursor/contentrain.cursorrules +2959 -0
- package/ide/generic/contentrain.md +2984 -0
- package/ide/windsurf/contentrain.windsurfrules +2984 -0
- package/package.json +61 -0
- package/prompts/common.md +81 -0
- package/prompts/generate-mode.md +195 -0
- package/prompts/normalize-mode.md +360 -0
- package/prompts/review-mode.md +241 -0
- package/shared/accessibility-rules.md +155 -0
- package/shared/content-conventions.md +314 -0
- package/shared/content-quality.md +294 -0
- package/shared/i18n-quality.md +293 -0
- package/shared/mcp-usage.md +405 -0
- package/shared/media-rules.md +165 -0
- package/shared/normalize-rules.md +312 -0
- package/shared/schema-rules.md +380 -0
- package/shared/security-rules.md +141 -0
- package/shared/seo-rules.md +224 -0
- package/shared/workflow-rules.md +262 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Contentrain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# `@contentrain/rules`
|
|
2
|
+
|
|
3
|
+
Shared AI-agent rules for Contentrain.
|
|
4
|
+
|
|
5
|
+
This package is the policy layer of the Contentrain ecosystem. It defines how agents should behave when they work with:
|
|
6
|
+
|
|
7
|
+
- Contentrain MCP tools
|
|
8
|
+
- schema and model design
|
|
9
|
+
- content quality
|
|
10
|
+
- normalize workflows
|
|
11
|
+
- git-backed review flows
|
|
12
|
+
- IDE rule distribution
|
|
13
|
+
|
|
14
|
+
If `@contentrain/mcp` is the deterministic execution layer, `@contentrain/rules` is the behavioral contract.
|
|
15
|
+
|
|
16
|
+
## 🚀 Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add @contentrain/rules
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 📦 What It Contains
|
|
23
|
+
|
|
24
|
+
### Shared rule sets
|
|
25
|
+
|
|
26
|
+
Published under `shared/*`:
|
|
27
|
+
|
|
28
|
+
- `content-quality.md`
|
|
29
|
+
- `seo-rules.md`
|
|
30
|
+
- `i18n-quality.md`
|
|
31
|
+
- `accessibility-rules.md`
|
|
32
|
+
- `security-rules.md`
|
|
33
|
+
- `media-rules.md`
|
|
34
|
+
- `content-conventions.md`
|
|
35
|
+
- `schema-rules.md`
|
|
36
|
+
- `mcp-usage.md`
|
|
37
|
+
- `workflow-rules.md`
|
|
38
|
+
- `normalize-rules.md`
|
|
39
|
+
|
|
40
|
+
### Prompt layers
|
|
41
|
+
|
|
42
|
+
Published under `prompts/*`:
|
|
43
|
+
|
|
44
|
+
- `common.md`
|
|
45
|
+
- `generate-mode.md`
|
|
46
|
+
- `normalize-mode.md`
|
|
47
|
+
- `review-mode.md`
|
|
48
|
+
|
|
49
|
+
### Context bridge
|
|
50
|
+
|
|
51
|
+
Published under `context/*`:
|
|
52
|
+
|
|
53
|
+
- `context-bridge.md`
|
|
54
|
+
|
|
55
|
+
### IDE bundles
|
|
56
|
+
|
|
57
|
+
Published under `ide/*`:
|
|
58
|
+
|
|
59
|
+
- `ide/claude-code/contentrain.md`
|
|
60
|
+
- `ide/cursor/contentrain.cursorrules`
|
|
61
|
+
- `ide/windsurf/contentrain.windsurfrules`
|
|
62
|
+
- `ide/generic/contentrain.md`
|
|
63
|
+
|
|
64
|
+
## 🧰 Public Exports
|
|
65
|
+
|
|
66
|
+
The package root exports constants that can be used by tooling:
|
|
67
|
+
|
|
68
|
+
- `FIELD_TYPES`
|
|
69
|
+
- `MODEL_KINDS`
|
|
70
|
+
- `MCP_TOOLS`
|
|
71
|
+
- `CONTENT_QUALITY_RULES`
|
|
72
|
+
- `ARCHITECTURE_RULES`
|
|
73
|
+
- `ALL_SHARED_RULES`
|
|
74
|
+
- `IDE_RULE_FILES`
|
|
75
|
+
- `STACKS`
|
|
76
|
+
|
|
77
|
+
## 🧪 Example
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { IDE_RULE_FILES, MCP_TOOLS, ALL_SHARED_RULES } from '@contentrain/rules'
|
|
81
|
+
|
|
82
|
+
console.log(MCP_TOOLS.includes('contentrain_validate'))
|
|
83
|
+
console.log(IDE_RULE_FILES['claude-code'])
|
|
84
|
+
console.log(ALL_SHARED_RULES)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 🧠Design Role
|
|
88
|
+
|
|
89
|
+
`@contentrain/rules` exists to keep agent behavior aligned across tools and environments.
|
|
90
|
+
|
|
91
|
+
It should answer questions like:
|
|
92
|
+
|
|
93
|
+
- What is acceptable content quality?
|
|
94
|
+
- How should an agent use MCP tools?
|
|
95
|
+
- What is the normalize contract?
|
|
96
|
+
- What workflow and review constraints exist?
|
|
97
|
+
- How should rules be packaged for Claude Code, Cursor, Windsurf, and generic agents?
|
|
98
|
+
|
|
99
|
+
## 🔗 Relationship To Other Packages
|
|
100
|
+
|
|
101
|
+
- `@contentrain/mcp` enforces file, validation, and git behavior
|
|
102
|
+
- `@contentrain/skills` provides step-by-step workflow playbooks
|
|
103
|
+
- `contentrain` exposes CLI and serve UX
|
|
104
|
+
- `@contentrain/query` is the generated runtime consumption layer
|
|
105
|
+
|
|
106
|
+
Rule of thumb:
|
|
107
|
+
|
|
108
|
+
- `rules` = policy and constraints
|
|
109
|
+
- `skills` = procedures and playbooks
|
|
110
|
+
|
|
111
|
+
## 🛠Build
|
|
112
|
+
|
|
113
|
+
The build does two things:
|
|
114
|
+
|
|
115
|
+
1. builds the typed JS entry from `src/index.ts`
|
|
116
|
+
2. generates IDE bundle files from the shared markdown rules
|
|
117
|
+
|
|
118
|
+
From the monorepo root:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pnpm --filter @contentrain/rules build
|
|
122
|
+
pnpm --filter @contentrain/rules test
|
|
123
|
+
pnpm --filter @contentrain/rules typecheck
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 📄 License
|
|
127
|
+
|
|
128
|
+
MIT
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Context Bridge — `.contentrain/context.json` Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`context.json` is the project intelligence file. It provides AI agents and Contentrain Studio with structured knowledge about the project: its tech stack, content patterns, conventions, and normalize configuration.
|
|
6
|
+
|
|
7
|
+
- **Written by:** MCP tools (updated after every write operation)
|
|
8
|
+
- **Read by:** AI agents (at the start of every session) and Studio (for UI configuration)
|
|
9
|
+
- **Location:** `.contentrain/context.json`
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Agent Reading Protocol
|
|
14
|
+
|
|
15
|
+
Follow this exact sequence when starting any session:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
1. config.json — Project configuration (stack, locales, workflow, domains)
|
|
19
|
+
2. context.json — Project intelligence (conventions, scan settings, content patterns)
|
|
20
|
+
3. vocabulary.json — Canonical terms, brand terms, forbidden terms
|
|
21
|
+
4. models/ — Model definitions (contentrain_status provides a summary)
|
|
22
|
+
5. content/ — Existing content (contentrain_describe provides samples)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### When `context.json` Does Not Exist
|
|
26
|
+
|
|
27
|
+
If the file does not exist, use defaults from `config.json`:
|
|
28
|
+
- `stack`: from `config.json > stack`
|
|
29
|
+
- `locales`: from `config.json > locales`
|
|
30
|
+
- `tone`: default to `"professional"`
|
|
31
|
+
- `scan_dirs`: default to `["src"]` or `["."]` depending on stack
|
|
32
|
+
- `scan_extensions`: default to framework-appropriate extensions
|
|
33
|
+
|
|
34
|
+
### Override Priority
|
|
35
|
+
|
|
36
|
+
`context.json` values take priority over static rule defaults. For example:
|
|
37
|
+
- If `context.json > conventions.max_title_length` is set to `80`, use `80` instead of the default `60` from `content-quality.md`.
|
|
38
|
+
- If `context.json > conventions.allowed_richtext_tags` is defined, use that list instead of the default from `security-rules.md`.
|
|
39
|
+
- Static rules are the fallback when `context.json` does not specify a value.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Schema
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"version": 1,
|
|
48
|
+
"project": {
|
|
49
|
+
"name": "my-project",
|
|
50
|
+
"description": "Project description for agent context",
|
|
51
|
+
"stack": "nuxt",
|
|
52
|
+
"stack_version": "3.x",
|
|
53
|
+
"package_manager": "pnpm",
|
|
54
|
+
"src_dir": ".",
|
|
55
|
+
"content_consumption": "build-time"
|
|
56
|
+
},
|
|
57
|
+
"content": {
|
|
58
|
+
"import_pattern": "import {model} from '~/.contentrain/content/{domain}/{model}/{locale}.json'",
|
|
59
|
+
"i18n_strategy": "file-per-locale",
|
|
60
|
+
"default_locale": "en",
|
|
61
|
+
"supported_locales": ["en", "tr"],
|
|
62
|
+
"domains": [
|
|
63
|
+
{
|
|
64
|
+
"id": "marketing",
|
|
65
|
+
"description": "Landing page content",
|
|
66
|
+
"models": ["hero", "features", "pricing"]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "blog",
|
|
70
|
+
"description": "Blog posts and categories",
|
|
71
|
+
"models": ["blog-post", "categories"]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"normalize": {
|
|
76
|
+
"scan_dirs": ["components", "pages", "layouts"],
|
|
77
|
+
"scan_extensions": [".vue", ".ts"],
|
|
78
|
+
"ignore_patterns": ["node_modules", ".nuxt", "dist", ".contentrain"],
|
|
79
|
+
"import_rewrite": "import { t } from '~/composables/useContent'"
|
|
80
|
+
},
|
|
81
|
+
"conventions": {
|
|
82
|
+
"tone": "Professional, concise. Avoid jargon.",
|
|
83
|
+
"brand_terms": {
|
|
84
|
+
"product_name": "Acme Platform",
|
|
85
|
+
"company_name": "Acme Inc"
|
|
86
|
+
},
|
|
87
|
+
"forbidden_terms": ["click here", "lorem ipsum", "TODO"],
|
|
88
|
+
"max_title_length": 80,
|
|
89
|
+
"max_description_length": 160,
|
|
90
|
+
"target_reading_level": "grade-8",
|
|
91
|
+
"allowed_richtext_tags": [
|
|
92
|
+
"p", "strong", "em", "a", "ul", "ol", "li",
|
|
93
|
+
"h2", "h3", "h4", "h5", "h6",
|
|
94
|
+
"blockquote", "code", "pre", "img", "br", "hr",
|
|
95
|
+
"table", "thead", "tbody", "tr", "th", "td",
|
|
96
|
+
"del", "ins", "sup", "sub", "abbr", "mark",
|
|
97
|
+
"details", "summary"
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"lastOperation": {
|
|
101
|
+
"tool": "content_save",
|
|
102
|
+
"model": "blog-post",
|
|
103
|
+
"locale": "en",
|
|
104
|
+
"entries": ["a1b2c3d4e5f6"],
|
|
105
|
+
"timestamp": "2026-03-11T14:30:00Z",
|
|
106
|
+
"source": "mcp-local"
|
|
107
|
+
},
|
|
108
|
+
"stats": {
|
|
109
|
+
"models": 5,
|
|
110
|
+
"entries": 142,
|
|
111
|
+
"locales": ["en", "tr"],
|
|
112
|
+
"lastSync": "2026-03-11T14:30:00Z"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Field Reference
|
|
120
|
+
|
|
121
|
+
### `version` (number)
|
|
122
|
+
|
|
123
|
+
Schema version. Currently `1`. Incremented on breaking schema changes.
|
|
124
|
+
|
|
125
|
+
### `project` (object)
|
|
126
|
+
|
|
127
|
+
| Field | Type | Description |
|
|
128
|
+
|-------|------|-------------|
|
|
129
|
+
| `name` | string | Project name. Used in branch names and commit messages. |
|
|
130
|
+
| `description` | string | Brief description for agent context. Helps agents understand the project purpose. |
|
|
131
|
+
| `stack` | string | Framework: `nuxt`, `next`, `astro`, `sveltekit`, `react`, `vue`, `node`. |
|
|
132
|
+
| `stack_version` | string | Framework version: `"3.x"`, `"14.x"`, `"4.x"`. Affects API patterns. |
|
|
133
|
+
| `package_manager` | string | `npm`, `pnpm`, `yarn`, `bun`. Affects install commands in suggestions. |
|
|
134
|
+
| `src_dir` | string | Source directory relative to project root. `"."` for Nuxt, `"src"` for most others. |
|
|
135
|
+
| `content_consumption` | string | How content is consumed: `"build-time"`, `"runtime"`, `"hybrid"`. |
|
|
136
|
+
|
|
137
|
+
### `content` (object)
|
|
138
|
+
|
|
139
|
+
| Field | Type | Description |
|
|
140
|
+
|-------|------|-------------|
|
|
141
|
+
| `import_pattern` | string | Content import template with `{model}`, `{domain}`, `{locale}` placeholders. |
|
|
142
|
+
| `i18n_strategy` | string | Localization strategy: `"file-per-locale"` or `"single-file"`. |
|
|
143
|
+
| `default_locale` | string | Default locale code (ISO 639-1): `"en"`, `"tr"`, `"de"`. |
|
|
144
|
+
| `supported_locales` | string[] | All supported locale codes. |
|
|
145
|
+
| `domains` | object[] | Content domain definitions. Each has `id` (string), `description` (string), and `models` (string[]). |
|
|
146
|
+
|
|
147
|
+
### `normalize` (object)
|
|
148
|
+
|
|
149
|
+
| Field | Type | Description |
|
|
150
|
+
|-------|------|-------------|
|
|
151
|
+
| `scan_dirs` | string[] | Directories to scan for hardcoded strings (relative to project root). |
|
|
152
|
+
| `scan_extensions` | string[] | File extensions to include in scan. |
|
|
153
|
+
| `ignore_patterns` | string[] | Glob patterns to exclude from scanning. |
|
|
154
|
+
| `import_rewrite` | string | Import statement used when rewriting source files after normalization. |
|
|
155
|
+
|
|
156
|
+
### `conventions` (object)
|
|
157
|
+
|
|
158
|
+
| Field | Type | Description |
|
|
159
|
+
|-------|------|-------------|
|
|
160
|
+
| `tone` | string | Content tone: `"professional"`, `"casual"`, `"technical"`, `"friendly"`, `"formal"`. |
|
|
161
|
+
| `brand_terms` | object | Key-value pairs of brand terms that must be used with exact casing and spelling. |
|
|
162
|
+
| `forbidden_terms` | string[] | Terms that must never appear in content. |
|
|
163
|
+
| `max_title_length` | number | Override for maximum title character count. Default: `60`. |
|
|
164
|
+
| `max_description_length` | number | Override for maximum description character count. Default: `160`. |
|
|
165
|
+
| `target_reading_level` | string | Target readability: `"grade-6"`, `"grade-8"`, `"grade-10"`, `"technical"`. |
|
|
166
|
+
| `allowed_richtext_tags` | string[] | Override for allowed HTML tags in richtext fields. |
|
|
167
|
+
|
|
168
|
+
### `lastOperation` (object)
|
|
169
|
+
|
|
170
|
+
Updated after every MCP write operation. Agents can use this to understand what changed most recently.
|
|
171
|
+
|
|
172
|
+
| Field | Type | Description |
|
|
173
|
+
|-------|------|-------------|
|
|
174
|
+
| `tool` | string | MCP tool that performed the operation: `"content_save"`, `"model_save"`, `"scaffold"`, `"apply"`. |
|
|
175
|
+
| `model` | string | Model ID that was affected. |
|
|
176
|
+
| `locale` | string | Locale of the operation (if applicable). |
|
|
177
|
+
| `entries` | string[] | Entry IDs that were created or modified. |
|
|
178
|
+
| `timestamp` | string | ISO 8601 timestamp of the operation. |
|
|
179
|
+
| `source` | string | Origin: `"mcp-local"` (IDE), `"mcp-studio"` (Studio server-side MCP), `"studio-ui"` (Studio direct). |
|
|
180
|
+
|
|
181
|
+
### `stats` (object)
|
|
182
|
+
|
|
183
|
+
Aggregate project statistics, updated after every write operation.
|
|
184
|
+
|
|
185
|
+
| Field | Type | Description |
|
|
186
|
+
|-------|------|-------------|
|
|
187
|
+
| `models` | number | Total number of models in the project. |
|
|
188
|
+
| `entries` | number | Total number of content entries across all models and locales. |
|
|
189
|
+
| `locales` | string[] | All locales that have content. |
|
|
190
|
+
| `lastSync` | string | ISO 8601 timestamp of the last sync operation. |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Stack-Specific Defaults
|
|
195
|
+
|
|
196
|
+
When creating `context.json` for the first time, use stack-appropriate defaults. See template files in `context/templates/` for each supported stack:
|
|
197
|
+
|
|
198
|
+
| Stack | Template | `src_dir` | `scan_extensions` | `scan_dirs` |
|
|
199
|
+
|-------|----------|-----------|-------------------|-------------|
|
|
200
|
+
| Nuxt | `nuxt.context.json` | `"app/"` | `[".vue", ".ts"]` | `["app/components/", "app/pages/", "app/layouts/"]` |
|
|
201
|
+
| Next.js | `next.context.json` | `"src/"` | `[".tsx", ".ts", ".jsx"]` | `["src/components/", "src/app/"]` |
|
|
202
|
+
| Astro | `astro.context.json` | `"src/"` | `[".astro", ".ts", ".tsx"]` | `["src/components/", "src/pages/", "src/layouts/"]` |
|
|
203
|
+
| SvelteKit | `sveltekit.context.json` | `"src/"` | `[".svelte", ".ts"]` | `["src/lib/", "src/routes/"]` |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Update Behavior
|
|
208
|
+
|
|
209
|
+
MCP tools update `context.json` after every write operation:
|
|
210
|
+
- `contentrain_init` creates the initial file
|
|
211
|
+
- `contentrain_model_save` updates the domains list if a new domain is used
|
|
212
|
+
- `contentrain_content_save` updates content stats
|
|
213
|
+
- `contentrain_apply` updates normalize state
|
|
214
|
+
- `contentrain_submit` updates last operation timestamp
|
|
215
|
+
|
|
216
|
+
Agents MUST NOT write to `context.json` directly. It is managed exclusively by MCP tools. Agents read it for configuration and intelligence.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Example: Reading Context in an Agent Session
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
1. Agent receives user request: "Add a blog post about deployment"
|
|
224
|
+
2. Agent reads config.json:
|
|
225
|
+
- stack: "nuxt"
|
|
226
|
+
- locales: ["en", "tr"]
|
|
227
|
+
- workflow: "review"
|
|
228
|
+
3. Agent reads context.json:
|
|
229
|
+
- tone: "professional"
|
|
230
|
+
- i18n_strategy: "@nuxtjs/i18n"
|
|
231
|
+
- domains: ["blog", "marketing"]
|
|
232
|
+
4. Agent reads vocabulary.json:
|
|
233
|
+
- brand_terms: ["Contentrain"]
|
|
234
|
+
- forbidden_terms: ["click here"]
|
|
235
|
+
5. Agent calls contentrain_status:
|
|
236
|
+
- Models: blog-post (document), categories (collection), authors (collection)
|
|
237
|
+
6. Agent calls contentrain_describe(model: "blog-post"):
|
|
238
|
+
- Fields: title (string, required), slug (slug, required, unique), excerpt (text), ...
|
|
239
|
+
7. Agent creates content following all rules, using vocabulary terms, matching tone
|
|
240
|
+
8. Agent validates and submits
|
|
241
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"project": {
|
|
4
|
+
"name": "my-astro-site",
|
|
5
|
+
"description": "Content-driven marketing site with blog and portfolio",
|
|
6
|
+
"stack": "astro",
|
|
7
|
+
"stack_version": "5.x",
|
|
8
|
+
"package_manager": "pnpm",
|
|
9
|
+
"src_dir": "src/",
|
|
10
|
+
"content_consumption": "build-time"
|
|
11
|
+
},
|
|
12
|
+
"content": {
|
|
13
|
+
"import_pattern": "import {model} from '~/.contentrain/content/{domain}/{model}/{locale}.json'",
|
|
14
|
+
"i18n_strategy": "file-per-locale",
|
|
15
|
+
"default_locale": "en",
|
|
16
|
+
"supported_locales": ["en", "de"],
|
|
17
|
+
"domains": [
|
|
18
|
+
{
|
|
19
|
+
"id": "marketing",
|
|
20
|
+
"description": "Landing page content — hero, features, testimonials",
|
|
21
|
+
"models": ["hero", "features", "testimonials"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "blog",
|
|
25
|
+
"description": "Blog posts, authors, and categories",
|
|
26
|
+
"models": ["blog-post", "authors", "categories"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "portfolio",
|
|
30
|
+
"description": "Project showcase entries",
|
|
31
|
+
"models": ["projects"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"normalize": {
|
|
36
|
+
"scan_dirs": ["src/components/", "src/pages/", "src/layouts/"],
|
|
37
|
+
"scan_extensions": [".astro", ".ts", ".tsx"],
|
|
38
|
+
"ignore_patterns": ["dist/", "node_modules/", ".astro/", ".contentrain/", "*.test.*", "*.spec.*"],
|
|
39
|
+
"import_rewrite": "import { t } from '../i18n/utils'"
|
|
40
|
+
},
|
|
41
|
+
"conventions": {
|
|
42
|
+
"tone": "Friendly, informative. Approachable but professional.",
|
|
43
|
+
"brand_terms": {
|
|
44
|
+
"product_name": "My Astro Site",
|
|
45
|
+
"company_name": "Stellar Labs"
|
|
46
|
+
},
|
|
47
|
+
"forbidden_terms": ["click here", "lorem ipsum", "TODO"],
|
|
48
|
+
"max_title_length": 80,
|
|
49
|
+
"max_description_length": 160,
|
|
50
|
+
"target_reading_level": "grade-8",
|
|
51
|
+
"allowed_richtext_tags": [
|
|
52
|
+
"p", "strong", "em", "a", "ul", "ol", "li",
|
|
53
|
+
"h2", "h3", "h4", "h5", "h6",
|
|
54
|
+
"blockquote", "code", "pre", "img", "br", "hr",
|
|
55
|
+
"table", "thead", "tbody", "tr", "th", "td",
|
|
56
|
+
"del", "ins", "sup", "sub", "abbr", "mark",
|
|
57
|
+
"details", "summary"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"lastOperation": {
|
|
61
|
+
"tool": "content_save",
|
|
62
|
+
"model": "blog-post",
|
|
63
|
+
"locale": "en",
|
|
64
|
+
"entries": ["c3d4e5f6a7b8"],
|
|
65
|
+
"timestamp": "2026-03-09T12:15:00Z",
|
|
66
|
+
"source": "mcp-local"
|
|
67
|
+
},
|
|
68
|
+
"stats": {
|
|
69
|
+
"models": 6,
|
|
70
|
+
"entries": 38,
|
|
71
|
+
"locales": ["en", "de"],
|
|
72
|
+
"lastSync": "2026-03-09T12:15:00Z"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"project": {
|
|
4
|
+
"name": "my-next-app",
|
|
5
|
+
"description": "SaaS marketing site with documentation and blog",
|
|
6
|
+
"stack": "next",
|
|
7
|
+
"stack_version": "15.x",
|
|
8
|
+
"package_manager": "npm",
|
|
9
|
+
"src_dir": "src/",
|
|
10
|
+
"content_consumption": "build-time"
|
|
11
|
+
},
|
|
12
|
+
"content": {
|
|
13
|
+
"import_pattern": "import {model} from '@/.contentrain/content/{domain}/{model}/{locale}.json'",
|
|
14
|
+
"i18n_strategy": "file-per-locale",
|
|
15
|
+
"default_locale": "en",
|
|
16
|
+
"supported_locales": ["en", "es", "fr"],
|
|
17
|
+
"domains": [
|
|
18
|
+
{
|
|
19
|
+
"id": "marketing",
|
|
20
|
+
"description": "Landing page content — hero, features, pricing, FAQ",
|
|
21
|
+
"models": ["hero", "features", "pricing", "faq"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "docs",
|
|
25
|
+
"description": "Documentation pages and sidebar navigation",
|
|
26
|
+
"models": ["doc-page", "doc-sidebar"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "blog",
|
|
30
|
+
"description": "Blog articles and tags",
|
|
31
|
+
"models": ["blog-post", "tags"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"normalize": {
|
|
36
|
+
"scan_dirs": ["src/components/", "src/app/"],
|
|
37
|
+
"scan_extensions": [".tsx", ".ts", ".jsx"],
|
|
38
|
+
"ignore_patterns": [".next/", "node_modules/", "out/", ".contentrain/", "*.test.*", "*.spec.*"],
|
|
39
|
+
"import_rewrite": "import { useTranslations } from 'next-intl'"
|
|
40
|
+
},
|
|
41
|
+
"conventions": {
|
|
42
|
+
"tone": "Professional, clear. Developer-friendly language.",
|
|
43
|
+
"brand_terms": {
|
|
44
|
+
"product_name": "My Next App",
|
|
45
|
+
"company_name": "Acme Corp"
|
|
46
|
+
},
|
|
47
|
+
"forbidden_terms": ["click here", "lorem ipsum", "TODO", "TBD"],
|
|
48
|
+
"max_title_length": 70,
|
|
49
|
+
"max_description_length": 155,
|
|
50
|
+
"target_reading_level": "grade-8",
|
|
51
|
+
"allowed_richtext_tags": [
|
|
52
|
+
"p", "strong", "em", "a", "ul", "ol", "li",
|
|
53
|
+
"h2", "h3", "h4", "h5", "h6",
|
|
54
|
+
"blockquote", "code", "pre", "img", "br", "hr",
|
|
55
|
+
"table", "thead", "tbody", "tr", "th", "td",
|
|
56
|
+
"del", "ins", "sup", "sub", "abbr", "mark",
|
|
57
|
+
"details", "summary"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"lastOperation": {
|
|
61
|
+
"tool": "model_save",
|
|
62
|
+
"model": "blog-post",
|
|
63
|
+
"locale": "en",
|
|
64
|
+
"entries": [],
|
|
65
|
+
"timestamp": "2026-03-10T16:45:00Z",
|
|
66
|
+
"source": "mcp-local"
|
|
67
|
+
},
|
|
68
|
+
"stats": {
|
|
69
|
+
"models": 7,
|
|
70
|
+
"entries": 54,
|
|
71
|
+
"locales": ["en", "es", "fr"],
|
|
72
|
+
"lastSync": "2026-03-10T16:45:00Z"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"project": {
|
|
4
|
+
"name": "my-nuxt-app",
|
|
5
|
+
"description": "Marketing website with blog and i18n support",
|
|
6
|
+
"stack": "nuxt",
|
|
7
|
+
"stack_version": "4.0",
|
|
8
|
+
"package_manager": "pnpm",
|
|
9
|
+
"src_dir": "app/",
|
|
10
|
+
"content_consumption": "build-time"
|
|
11
|
+
},
|
|
12
|
+
"content": {
|
|
13
|
+
"import_pattern": "import {model} from '~/.contentrain/content/{domain}/{model}/{locale}.json'",
|
|
14
|
+
"i18n_strategy": "file-per-locale",
|
|
15
|
+
"default_locale": "en",
|
|
16
|
+
"supported_locales": ["en", "tr"],
|
|
17
|
+
"domains": [
|
|
18
|
+
{
|
|
19
|
+
"id": "marketing",
|
|
20
|
+
"description": "Landing page content — hero, features, pricing, testimonials",
|
|
21
|
+
"models": ["hero", "features", "pricing", "testimonials"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "blog",
|
|
25
|
+
"description": "Blog posts and categories",
|
|
26
|
+
"models": ["blog-post", "categories"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "ui",
|
|
30
|
+
"description": "UI strings — navigation, forms, errors",
|
|
31
|
+
"models": ["navigation", "forms", "error-messages"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"normalize": {
|
|
36
|
+
"scan_dirs": ["app/components/", "app/pages/", "app/layouts/"],
|
|
37
|
+
"scan_extensions": [".vue", ".ts"],
|
|
38
|
+
"ignore_patterns": [".nuxt/", "node_modules/", "dist/", ".contentrain/", "*.test.*", "*.spec.*"],
|
|
39
|
+
"import_rewrite": "import { t } from '~/composables/useContent'"
|
|
40
|
+
},
|
|
41
|
+
"conventions": {
|
|
42
|
+
"tone": "Professional, concise. Avoid jargon.",
|
|
43
|
+
"brand_terms": {
|
|
44
|
+
"product_name": "My Nuxt App",
|
|
45
|
+
"company_name": "Acme Inc"
|
|
46
|
+
},
|
|
47
|
+
"forbidden_terms": ["click here", "lorem ipsum", "TODO"],
|
|
48
|
+
"max_title_length": 80,
|
|
49
|
+
"max_description_length": 160,
|
|
50
|
+
"target_reading_level": "grade-8",
|
|
51
|
+
"allowed_richtext_tags": [
|
|
52
|
+
"p", "strong", "em", "a", "ul", "ol", "li",
|
|
53
|
+
"h2", "h3", "h4", "h5", "h6",
|
|
54
|
+
"blockquote", "code", "pre", "img", "br", "hr",
|
|
55
|
+
"table", "thead", "tbody", "tr", "th", "td",
|
|
56
|
+
"del", "ins", "sup", "sub", "abbr", "mark",
|
|
57
|
+
"details", "summary"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"lastOperation": {
|
|
61
|
+
"tool": "content_save",
|
|
62
|
+
"model": "hero",
|
|
63
|
+
"locale": "en",
|
|
64
|
+
"entries": ["f7e8d9c0b1a2"],
|
|
65
|
+
"timestamp": "2026-03-11T10:00:00Z",
|
|
66
|
+
"source": "mcp-local"
|
|
67
|
+
},
|
|
68
|
+
"stats": {
|
|
69
|
+
"models": 7,
|
|
70
|
+
"entries": 86,
|
|
71
|
+
"locales": ["en", "tr"],
|
|
72
|
+
"lastSync": "2026-03-11T10:00:00Z"
|
|
73
|
+
}
|
|
74
|
+
}
|