@contentrain/skills 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 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,102 @@
1
+ # `@contentrain/skills`
2
+
3
+ Workflow skills and framework guides for Contentrain-aware AI agents.
4
+
5
+ This package is the procedural layer of the Contentrain ecosystem. It tells an agent how to apply the policy from `@contentrain/rules` in concrete tasks such as:
6
+
7
+ - initializing a project
8
+ - creating content
9
+ - running normalize
10
+ - reviewing and submitting changes
11
+ - generating the SDK client
12
+ - translating content
13
+
14
+ If `@contentrain/rules` defines constraints, `@contentrain/skills` defines execution playbooks.
15
+
16
+ ## ๐Ÿš€ Install
17
+
18
+ ```bash
19
+ pnpm add @contentrain/skills
20
+ ```
21
+
22
+ ## ๐Ÿ“ฆ What It Contains
23
+
24
+ ### Workflow skills
25
+
26
+ Published under `workflows/*`:
27
+
28
+ - `contentrain-init.md`
29
+ - `contentrain-model.md`
30
+ - `contentrain-content.md`
31
+ - `contentrain-bulk.md`
32
+ - `contentrain-normalize.md`
33
+ - `contentrain-validate-fix.md`
34
+ - `contentrain-review.md`
35
+ - `contentrain-diff.md`
36
+ - `contentrain-doctor.md`
37
+ - `contentrain-serve.md`
38
+ - `contentrain-translate.md`
39
+ - `contentrain-generate.md`
40
+
41
+ ### Framework guides
42
+
43
+ Published under `frameworks/*`:
44
+
45
+ - `nuxt.md`
46
+ - `next.md`
47
+ - `astro.md`
48
+ - `sveltekit.md`
49
+ - `vue.md`
50
+ - `react.md`
51
+ - `expo.md`
52
+ - `react-native.md`
53
+ - `node.md`
54
+
55
+ ## ๐Ÿงฐ Public Exports
56
+
57
+ The package root exports:
58
+
59
+ - `WORKFLOW_SKILLS`
60
+ - `FRAMEWORK_GUIDES`
61
+
62
+ ## ๐Ÿงช Example
63
+
64
+ ```ts
65
+ import { WORKFLOW_SKILLS, FRAMEWORK_GUIDES } from '@contentrain/skills'
66
+
67
+ console.log(WORKFLOW_SKILLS)
68
+ console.log(FRAMEWORK_GUIDES.includes('next'))
69
+ ```
70
+
71
+ ## ๐Ÿง  Design Role
72
+
73
+ `@contentrain/skills` is for step-by-step execution guidance:
74
+
75
+ - `skills` = procedures and operational playbooks
76
+ - `rules` = policy and non-negotiable constraints
77
+
78
+ In practice:
79
+
80
+ - use `@contentrain/rules` to understand what is allowed
81
+ - use `@contentrain/skills` to decide which workflow to run next
82
+
83
+ ## ๐Ÿ”— Relationship To Other Packages
84
+
85
+ - `@contentrain/mcp` provides the actual tool surface
86
+ - `@contentrain/rules` defines policy and quality constraints
87
+ - `contentrain` exposes CLI and serve workflows
88
+ - `@contentrain/query` provides the generated content runtime
89
+
90
+ ## ๐Ÿ›  Build
91
+
92
+ From the monorepo root:
93
+
94
+ ```bash
95
+ pnpm --filter @contentrain/skills build
96
+ pnpm --filter @contentrain/skills test
97
+ pnpm --filter @contentrain/skills typecheck
98
+ ```
99
+
100
+ ## ๐Ÿ“„ License
101
+
102
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,35 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/index.ts
3
+ /**
4
+ * @contentrain/skills โ€” AI agent skills for Contentrain
5
+ *
6
+ * Step-by-step workflow procedures and framework integration guides.
7
+ */
8
+ const WORKFLOW_SKILLS = [
9
+ "contentrain-init",
10
+ "contentrain-model",
11
+ "contentrain-content",
12
+ "contentrain-bulk",
13
+ "contentrain-normalize",
14
+ "contentrain-validate-fix",
15
+ "contentrain-review",
16
+ "contentrain-diff",
17
+ "contentrain-doctor",
18
+ "contentrain-serve",
19
+ "contentrain-translate",
20
+ "contentrain-generate"
21
+ ];
22
+ const FRAMEWORK_GUIDES = [
23
+ "nuxt",
24
+ "next",
25
+ "astro",
26
+ "sveltekit",
27
+ "vue",
28
+ "react",
29
+ "expo",
30
+ "react-native",
31
+ "node"
32
+ ];
33
+ //#endregion
34
+ exports.FRAMEWORK_GUIDES = FRAMEWORK_GUIDES;
35
+ exports.WORKFLOW_SKILLS = WORKFLOW_SKILLS;
@@ -0,0 +1,13 @@
1
+ //#region src/index.d.ts
2
+ /**
3
+ * @contentrain/skills โ€” AI agent skills for Contentrain
4
+ *
5
+ * Step-by-step workflow procedures and framework integration guides.
6
+ */
7
+ declare const WORKFLOW_SKILLS: readonly ["contentrain-init", "contentrain-model", "contentrain-content", "contentrain-bulk", "contentrain-normalize", "contentrain-validate-fix", "contentrain-review", "contentrain-diff", "contentrain-doctor", "contentrain-serve", "contentrain-translate", "contentrain-generate"];
8
+ type WorkflowSkill = (typeof WORKFLOW_SKILLS)[number];
9
+ declare const FRAMEWORK_GUIDES: readonly ["nuxt", "next", "astro", "sveltekit", "vue", "react", "expo", "react-native", "node"];
10
+ type FrameworkGuide = (typeof FRAMEWORK_GUIDES)[number];
11
+ //#endregion
12
+ export { FRAMEWORK_GUIDES, FrameworkGuide, WORKFLOW_SKILLS, WorkflowSkill };
13
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;AAQA;;;;cAAa,eAAA;AAAA,KAeD,aAAA,WAAwB,eAAA;AAAA,cAIvB,gBAAA;AAAA,KACD,cAAA,WAAyB,gBAAA"}
@@ -0,0 +1,13 @@
1
+ //#region src/index.d.ts
2
+ /**
3
+ * @contentrain/skills โ€” AI agent skills for Contentrain
4
+ *
5
+ * Step-by-step workflow procedures and framework integration guides.
6
+ */
7
+ declare const WORKFLOW_SKILLS: readonly ["contentrain-init", "contentrain-model", "contentrain-content", "contentrain-bulk", "contentrain-normalize", "contentrain-validate-fix", "contentrain-review", "contentrain-diff", "contentrain-doctor", "contentrain-serve", "contentrain-translate", "contentrain-generate"];
8
+ type WorkflowSkill = (typeof WORKFLOW_SKILLS)[number];
9
+ declare const FRAMEWORK_GUIDES: readonly ["nuxt", "next", "astro", "sveltekit", "vue", "react", "expo", "react-native", "node"];
10
+ type FrameworkGuide = (typeof FRAMEWORK_GUIDES)[number];
11
+ //#endregion
12
+ export { FRAMEWORK_GUIDES, FrameworkGuide, WORKFLOW_SKILLS, WorkflowSkill };
13
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;AAQA;;;;cAAa,eAAA;AAAA,KAeD,aAAA,WAAwB,eAAA;AAAA,cAIvB,gBAAA;AAAA,KACD,cAAA,WAAyB,gBAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,35 @@
1
+ //#region src/index.ts
2
+ /**
3
+ * @contentrain/skills โ€” AI agent skills for Contentrain
4
+ *
5
+ * Step-by-step workflow procedures and framework integration guides.
6
+ */
7
+ const WORKFLOW_SKILLS = [
8
+ "contentrain-init",
9
+ "contentrain-model",
10
+ "contentrain-content",
11
+ "contentrain-bulk",
12
+ "contentrain-normalize",
13
+ "contentrain-validate-fix",
14
+ "contentrain-review",
15
+ "contentrain-diff",
16
+ "contentrain-doctor",
17
+ "contentrain-serve",
18
+ "contentrain-translate",
19
+ "contentrain-generate"
20
+ ];
21
+ const FRAMEWORK_GUIDES = [
22
+ "nuxt",
23
+ "next",
24
+ "astro",
25
+ "sveltekit",
26
+ "vue",
27
+ "react",
28
+ "expo",
29
+ "react-native",
30
+ "node"
31
+ ];
32
+ //#endregion
33
+ export { FRAMEWORK_GUIDES, WORKFLOW_SKILLS };
34
+
35
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @contentrain/skills โ€” AI agent skills for Contentrain\n *\n * Step-by-step workflow procedures and framework integration guides.\n */\n\n// โ”€โ”€โ”€ Workflow Skills โ”€โ”€โ”€\n\nexport const WORKFLOW_SKILLS = [\n 'contentrain-init',\n 'contentrain-model',\n 'contentrain-content',\n 'contentrain-bulk',\n 'contentrain-normalize',\n 'contentrain-validate-fix',\n 'contentrain-review',\n 'contentrain-diff',\n 'contentrain-doctor',\n 'contentrain-serve',\n 'contentrain-translate',\n 'contentrain-generate',\n] as const\n\nexport type WorkflowSkill = (typeof WORKFLOW_SKILLS)[number]\n\n// โ”€โ”€โ”€ Framework Guides โ”€โ”€โ”€\n\nexport const FRAMEWORK_GUIDES = ['nuxt', 'next', 'astro', 'sveltekit', 'vue', 'react', 'expo', 'react-native', 'node'] as const\nexport type FrameworkGuide = (typeof FRAMEWORK_GUIDES)[number]\n"],"mappings":";;;;;;AAQA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAMD,MAAa,mBAAmB;CAAC;CAAQ;CAAQ;CAAS;CAAa;CAAO;CAAS;CAAQ;CAAgB;CAAO"}
@@ -0,0 +1,334 @@
1
+ # Contentrain + Astro
2
+
3
+ > Framework guide for consuming Contentrain-managed content in Astro projects.
4
+
5
+ ---
6
+
7
+ ## 1. Setup
8
+
9
+ ### 1.1 SDK Installation
10
+
11
+ ```bash
12
+ pnpm add @contentrain/query # or npm/yarn
13
+ npx contentrain generate
14
+ ```
15
+
16
+ The generator reads `.contentrain/models/` and produces a typed client in `.contentrain/client/`. Your `package.json` must include the subpath import:
17
+
18
+ ```json
19
+ {
20
+ "imports": {
21
+ "#contentrain": {
22
+ "types": "./.contentrain/client/index.d.ts",
23
+ "import": "./.contentrain/client/index.mjs",
24
+ "require": "./.contentrain/client/index.cjs",
25
+ "default": "./.contentrain/client/index.mjs"
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ The generator adds this automatically. Restart the Astro dev server after initial generation.
32
+
33
+ ### 1.2 Watch Mode
34
+
35
+ Run the generator alongside Astro dev:
36
+
37
+ ```bash
38
+ npx contentrain generate --watch &
39
+ npx astro dev
40
+ ```
41
+
42
+ ---
43
+
44
+ ## 2. Imports
45
+
46
+ All SDK functions are imported from the `#contentrain` subpath:
47
+
48
+ ```ts
49
+ import { query, singleton, dictionary, document } from '#contentrain'
50
+ ```
51
+
52
+ This import works in `.astro` component frontmatter, API routes, and any server-side script. The SDK reads JSON files from the file system โ€” no runtime API calls.
53
+
54
+ ---
55
+
56
+ ## 3. Querying Content
57
+
58
+ ### 3.1 Collections
59
+
60
+ ```ts
61
+ const posts = query('blog-post').locale('en').all()
62
+ const featured = query('blog-post').locale('en').where('featured', true).all()
63
+ const sorted = query('blog-post').locale('en').sort('publishedAt', 'desc').all()
64
+ const post = query('blog-post').locale('en').where('id', 'abc-123').first()
65
+ ```
66
+
67
+ ### 3.2 Singletons
68
+
69
+ ```ts
70
+ const hero = singleton('hero').locale('en').get()
71
+ ```
72
+
73
+ ### 3.3 Dictionaries
74
+
75
+ ```ts
76
+ const label = dictionary('ui-labels').locale('en').get('submit_button')
77
+ const allLabels = dictionary('ui-labels').locale('en').get()
78
+ ```
79
+
80
+ ### 3.4 Documents
81
+
82
+ ```ts
83
+ const article = document('blog-article').locale('en').bySlug('getting-started')
84
+ ```
85
+
86
+ ### 3.5 Relations
87
+
88
+ ```ts
89
+ const posts = query('blog-post').locale('en').include('author', 'tags').all()
90
+ // post.author โ†’ full author object
91
+ // post.tags โ†’ array of full tag objects
92
+ ```
93
+
94
+ ---
95
+
96
+ ## 4. Astro Integration Patterns
97
+
98
+ ### 4.1 Page Components
99
+
100
+ SDK calls go in the frontmatter (the `---` fenced section):
101
+
102
+ ```astro
103
+ ---
104
+ import { query } from '#contentrain'
105
+
106
+ const posts = query('blog-post').locale('en').sort('publishedAt', 'desc').all()
107
+ ---
108
+
109
+ <ul>
110
+ {posts.map(post => (
111
+ <li><a href={`/blog/${post.slug}`}>{post.title}</a></li>
112
+ ))}
113
+ </ul>
114
+ ```
115
+
116
+ ### 4.2 Dynamic Routes
117
+
118
+ For `src/pages/blog/[slug].astro`:
119
+
120
+ ```astro
121
+ ---
122
+ import { query, document } from '#contentrain'
123
+
124
+ export function getStaticPaths() {
125
+ const posts = query('blog-post').locale('en').all()
126
+ return posts.map(post => ({
127
+ params: { slug: post.slug },
128
+ props: { post }
129
+ }))
130
+ }
131
+
132
+ const { post } = Astro.props
133
+ ---
134
+
135
+ <article>
136
+ <h1>{post.title}</h1>
137
+ </article>
138
+ ```
139
+
140
+ ### 4.3 Layout Data
141
+
142
+ Provide global content (navigation, footer) from layouts:
143
+
144
+ ```astro
145
+ ---
146
+ import { singleton, dictionary } from '#contentrain'
147
+
148
+ const nav = singleton('navigation').locale('en').get()
149
+ const footerLabels = dictionary('footer-labels').locale('en').get()
150
+ ---
151
+
152
+ <nav>
153
+ {nav.items.map(item => <a href={item.url}>{item.label}</a>)}
154
+ </nav>
155
+ <slot />
156
+ <footer>
157
+ <!-- footer content -->
158
+ </footer>
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 5. i18n Integration
164
+
165
+ ### 5.1 Astro Built-in i18n
166
+
167
+ Astro provides built-in i18n routing. Combine it with Contentrain locale support:
168
+
169
+ ```astro
170
+ ---
171
+ // src/pages/[locale]/blog/[slug].astro
172
+ import { document } from '#contentrain'
173
+
174
+ export function getStaticPaths() {
175
+ const locales = ['en', 'tr', 'de']
176
+ const paths = []
177
+ for (const locale of locales) {
178
+ const posts = document('blog-article').locale(locale).all()
179
+ for (const post of posts) {
180
+ paths.push({
181
+ params: { locale, slug: post.slug },
182
+ props: { post, locale }
183
+ })
184
+ }
185
+ }
186
+ return paths
187
+ }
188
+
189
+ const { post } = Astro.props
190
+ ---
191
+
192
+ <article>
193
+ <h1>{post.title}</h1>
194
+ </article>
195
+ ```
196
+
197
+ ### 5.2 Current Locale Access
198
+
199
+ Use `Astro.currentLocale` (available when i18n is configured in `astro.config.mjs`) to pass the locale to SDK calls:
200
+
201
+ ```astro
202
+ ---
203
+ import { query } from '#contentrain'
204
+
205
+ const locale = Astro.currentLocale ?? 'en'
206
+ const posts = query('blog-post').locale(locale).all()
207
+ ---
208
+ ```
209
+
210
+ ### 5.3 Dictionary Strings
211
+
212
+ Contentrain dictionaries can serve as the translation source for UI strings:
213
+
214
+ ```astro
215
+ ---
216
+ import { dictionary } from '#contentrain'
217
+
218
+ const locale = Astro.currentLocale ?? 'en'
219
+ const t = dictionary('ui-labels').locale(locale).get()
220
+ ---
221
+
222
+ <button>{t.submit_button}</button>
223
+ <p>{t.welcome_message}</p>
224
+ ```
225
+
226
+ ---
227
+
228
+ ## 6. Content Collections Integration
229
+
230
+ ### 6.1 Astro Content Collections
231
+
232
+ Astro's content collections can coexist with Contentrain. Define a collection that points to `.contentrain/content/`:
233
+
234
+ ```ts
235
+ // src/content/config.ts
236
+ import { defineCollection, z } from 'astro:content'
237
+
238
+ const blog = defineCollection({
239
+ type: 'content',
240
+ schema: z.object({
241
+ title: z.string(),
242
+ description: z.string(),
243
+ publishedAt: z.string()
244
+ })
245
+ })
246
+
247
+ export const collections = { blog }
248
+ ```
249
+
250
+ Symlink or copy `.contentrain/content/blog/` to `src/content/blog/` if using Astro's content layer, or use the SDK directly for simpler setups.
251
+
252
+ ### 6.2 Markdown Rendering
253
+
254
+ For document-kind entries with markdown bodies, render them using Astro's built-in markdown support or a markdown component:
255
+
256
+ ```astro
257
+ ---
258
+ import { document } from '#contentrain'
259
+
260
+ const article = document('blog-article').locale('en').bySlug('getting-started')
261
+ ---
262
+
263
+ <article>
264
+ <h1>{article.title}</h1>
265
+ <Fragment set:html={article.bodyHtml} />
266
+ </article>
267
+ ```
268
+
269
+ ---
270
+
271
+ ## 7. Islands Architecture
272
+
273
+ ### 7.1 Static Parent, Dynamic Child
274
+
275
+ Content data is fetched in the static Astro component and passed to interactive island components as props:
276
+
277
+ ```astro
278
+ ---
279
+ import { query } from '#contentrain'
280
+ import SearchWidget from '../components/SearchWidget.tsx'
281
+
282
+ const posts = query('blog-post').locale('en').all()
283
+ ---
284
+
285
+ <!-- Static content -->
286
+ <h1>Blog</h1>
287
+
288
+ <!-- Interactive island with content data -->
289
+ <SearchWidget client:load posts={posts} />
290
+ ```
291
+
292
+ The content is embedded in the static HTML. The island component receives it as serialized props โ€” no client-side data fetching required.
293
+
294
+ ---
295
+
296
+ ## 8. Build and Deployment
297
+
298
+ ### 8.1 Static Output (Default)
299
+
300
+ Astro builds static HTML by default. All SDK calls resolve at build time:
301
+
302
+ ```bash
303
+ npx astro build
304
+ ```
305
+
306
+ Output goes to `dist/`. Content is baked into the HTML โ€” zero runtime dependencies.
307
+
308
+ ### 8.2 SSR Mode
309
+
310
+ With SSR enabled (`output: 'server'` or `output: 'hybrid'` in `astro.config.mjs`), SDK calls execute on the server at request time. Content is still file-based.
311
+
312
+ ### 8.3 Deployment Flow
313
+
314
+ 1. Content changes are committed to Git via MCP tools.
315
+ 2. Push triggers platform rebuild (Vercel, Netlify, Cloudflare Pages).
316
+ 3. `astro build` runs, SDK reads `.contentrain/` content.
317
+ 4. Static pages are generated with embedded content.
318
+
319
+ ---
320
+
321
+ ## 9. Type Safety
322
+
323
+ The generated client provides full TypeScript types:
324
+
325
+ ```ts
326
+ import { query } from '#contentrain'
327
+
328
+ // Fully typed โ€” autocomplete for all fields
329
+ const posts = query('blog-post').locale('en').all()
330
+ posts[0].title // string
331
+ posts[0].author // Author type when using .include('author')
332
+ ```
333
+
334
+ Keep the generator running in watch mode during development to stay in sync with model changes.
@@ -0,0 +1,66 @@
1
+ # Contentrain + Expo / React Native
2
+
3
+ > Framework guide for Metro-style consumers of the generated Contentrain client.
4
+
5
+ ---
6
+
7
+ ## 1. Setup
8
+
9
+ ```bash
10
+ pnpm add @contentrain/query
11
+ npx contentrain generate
12
+ ```
13
+
14
+ The generated client exposes a CommonJS bootstrap path for Metro-like consumers.
15
+
16
+ ---
17
+
18
+ ## 2. Bootstrap Pattern
19
+
20
+ Use the CJS wrapper and initialize it once:
21
+
22
+ ```ts
23
+ // app/content.ts
24
+ let clientPromise: Promise<any> | null = null
25
+
26
+ export function getContentrainClient() {
27
+ if (!clientPromise) {
28
+ clientPromise = require('#contentrain').init()
29
+ }
30
+ return clientPromise
31
+ }
32
+ ```
33
+
34
+ Then use it from app code:
35
+
36
+ ```tsx
37
+ import { useEffect, useState } from 'react'
38
+ import { Text, View } from 'react-native'
39
+ import { getContentrainClient } from './content'
40
+
41
+ export function HomeScreen() {
42
+ const [title, setTitle] = useState('')
43
+
44
+ useEffect(() => {
45
+ getContentrainClient().then((client) => {
46
+ setTitle(client.singleton('hero').locale('en').get().title)
47
+ })
48
+ }, [])
49
+
50
+ return (
51
+ <View>
52
+ <Text>{title}</Text>
53
+ </View>
54
+ )
55
+ }
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 3. Rules
61
+
62
+ - use `require('#contentrain').init()` for the bootstrap
63
+ - cache the promise; do not initialize on every render
64
+ - treat the client as read-only generated data
65
+ - re-run `contentrain generate` after content/model changes
66
+